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 } 355b003df0Sstefano_zampini 365b003df0Sstefano_zampini #undef __FUNCT__ 375b003df0Sstefano_zampini #define __FUNCT__ "MatISContainerDestroyArray_Private" 385b003df0Sstefano_zampini static PetscErrorCode MatISContainerDestroyArray_Private(void *ptr) 396989cf23SStefano 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 { 168cf0a3239SStefano Zampini PetscErrorCode ierr; 169cf0a3239SStefano Zampini 170cf0a3239SStefano 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); 174cf0a3239SStefano Zampini PetscFunctionReturn(0); 175cf0a3239SStefano Zampini } 176a72627d2SStefano Zampini 17728f4e0baSStefano 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; 1875e3038f0Sstefano_zampini PetscBool convert,lreuse; 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); 2095e3038f0Sstefano_zampini ierr = PetscCalloc5(nr,&isrow,nc,&iscol, 2105e3038f0Sstefano_zampini nr,&islrow,nc,&islcol, 2115e3038f0Sstefano_zampini nr*nc,&snest);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; 2165e3038f0Sstefano_zampini PetscInt l1,l2,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 */ 2225e3038f0Sstefano_zampini ierr = PetscObjectTypeCompare((PetscObject)nest[i][j],MATIS,&ismatis);CHKERRQ(ierr); 2235e3038f0Sstefano_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); 2245e3038f0Sstefano_zampini 2255e3038f0Sstefano_zampini /* Check compatibility of local sizes */ 2265e3038f0Sstefano_zampini ierr = MatISGetLocalMat(nest[i][j],&snest[ij]);CHKERRQ(ierr); 2275e3038f0Sstefano_zampini ierr = MatGetSize(snest[ij],&l1,&l2);CHKERRQ(ierr); 2285e3038f0Sstefano_zampini if (!l1 || !l2) continue; 2295e3038f0Sstefano_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); 2305e3038f0Sstefano_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); 2315e3038f0Sstefano_zampini lr[i] = l1; 2325e3038f0Sstefano_zampini lc[j] = l2; 2335e3038f0Sstefano_zampini 2345e3038f0Sstefano_zampini /* check compatibilty for local matrix reusage */ 2355e3038f0Sstefano_zampini if (rnest && !rnest[i][j] != !snest[ij]) lreuse = PETSC_FALSE; 2365e3038f0Sstefano_zampini } 2375e3038f0Sstefano_zampini } 2385e3038f0Sstefano_zampini 2395e3038f0Sstefano_zampini #if defined (PETSC_USE_DEBUG) 2405e3038f0Sstefano_zampini /* Check compatibility of l2g maps for rows */ 2415e3038f0Sstefano_zampini for (i=0;i<nr;i++) { 2425e3038f0Sstefano_zampini rl2g = NULL; 2435e3038f0Sstefano_zampini for (j=0;j<nc;j++) { 2445e3038f0Sstefano_zampini PetscInt n1,n2; 2455e3038f0Sstefano_zampini 2465e3038f0Sstefano_zampini if (!nest[i][j]) continue; 2475e3038f0Sstefano_zampini ierr = MatGetLocalToGlobalMapping(nest[i][j],&cl2g,NULL);CHKERRQ(ierr); 2485e3038f0Sstefano_zampini ierr = ISLocalToGlobalMappingGetSize(cl2g,&n1);CHKERRQ(ierr); 2495e3038f0Sstefano_zampini if (!n1) continue; 2505e3038f0Sstefano_zampini if (!rl2g) { 2515e3038f0Sstefano_zampini rl2g = cl2g; 2525e3038f0Sstefano_zampini } else { 2535e3038f0Sstefano_zampini const PetscInt *idxs1,*idxs2; 2545e3038f0Sstefano_zampini PetscBool same; 2555e3038f0Sstefano_zampini 2565e3038f0Sstefano_zampini ierr = ISLocalToGlobalMappingGetSize(rl2g,&n2);CHKERRQ(ierr); 2575e3038f0Sstefano_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); 2585e3038f0Sstefano_zampini ierr = ISLocalToGlobalMappingGetIndices(cl2g,&idxs1);CHKERRQ(ierr); 2595e3038f0Sstefano_zampini ierr = ISLocalToGlobalMappingGetIndices(rl2g,&idxs2);CHKERRQ(ierr); 2605e3038f0Sstefano_zampini ierr = PetscMemcmp(idxs1,idxs2,n1*sizeof(PetscInt),&same);CHKERRQ(ierr); 2615e3038f0Sstefano_zampini ierr = ISLocalToGlobalMappingRestoreIndices(cl2g,&idxs1);CHKERRQ(ierr); 2625e3038f0Sstefano_zampini ierr = ISLocalToGlobalMappingRestoreIndices(rl2g,&idxs2);CHKERRQ(ierr); 2635e3038f0Sstefano_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); 2645e3038f0Sstefano_zampini } 2655e3038f0Sstefano_zampini } 2665e3038f0Sstefano_zampini } 2675e3038f0Sstefano_zampini /* Check compatibility of l2g maps for columns */ 2685e3038f0Sstefano_zampini for (i=0;i<nc;i++) { 2695e3038f0Sstefano_zampini rl2g = NULL; 2705e3038f0Sstefano_zampini for (j=0;j<nr;j++) { 2715e3038f0Sstefano_zampini PetscInt n1,n2; 2725e3038f0Sstefano_zampini 2735e3038f0Sstefano_zampini if (!nest[j][i]) continue; 2745e3038f0Sstefano_zampini ierr = MatGetLocalToGlobalMapping(nest[j][i],NULL,&cl2g);CHKERRQ(ierr); 2755e3038f0Sstefano_zampini ierr = ISLocalToGlobalMappingGetSize(cl2g,&n1);CHKERRQ(ierr); 2765e3038f0Sstefano_zampini if (!n1) continue; 2775e3038f0Sstefano_zampini if (!rl2g) { 2785e3038f0Sstefano_zampini rl2g = cl2g; 2795e3038f0Sstefano_zampini } else { 2805e3038f0Sstefano_zampini const PetscInt *idxs1,*idxs2; 2815e3038f0Sstefano_zampini PetscBool same; 2825e3038f0Sstefano_zampini 2835e3038f0Sstefano_zampini ierr = ISLocalToGlobalMappingGetSize(rl2g,&n2);CHKERRQ(ierr); 2845e3038f0Sstefano_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); 2855e3038f0Sstefano_zampini ierr = ISLocalToGlobalMappingGetIndices(cl2g,&idxs1);CHKERRQ(ierr); 2865e3038f0Sstefano_zampini ierr = ISLocalToGlobalMappingGetIndices(rl2g,&idxs2);CHKERRQ(ierr); 2875e3038f0Sstefano_zampini ierr = PetscMemcmp(idxs1,idxs2,n1*sizeof(PetscInt),&same);CHKERRQ(ierr); 2885e3038f0Sstefano_zampini ierr = ISLocalToGlobalMappingRestoreIndices(cl2g,&idxs1);CHKERRQ(ierr); 2895e3038f0Sstefano_zampini ierr = ISLocalToGlobalMappingRestoreIndices(rl2g,&idxs2);CHKERRQ(ierr); 2905e3038f0Sstefano_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); 2915e3038f0Sstefano_zampini } 2925e3038f0Sstefano_zampini } 2935e3038f0Sstefano_zampini } 2945e3038f0Sstefano_zampini #endif 2955e3038f0Sstefano_zampini 2965e3038f0Sstefano_zampini B = NULL; 2975e3038f0Sstefano_zampini if (reuse != MAT_REUSE_MATRIX) { 2985b003df0Sstefano_zampini PetscInt stl; 2995b003df0Sstefano_zampini 3005e3038f0Sstefano_zampini /* Create l2g map for the rows of the new matrix and index sets for the local MATNEST */ 3015e3038f0Sstefano_zampini for (i=0,stl=0;i<nr;i++) stl += lr[i]; 3025e3038f0Sstefano_zampini ierr = PetscMalloc1(stl,&l2gidxs);CHKERRQ(ierr); 3035b003df0Sstefano_zampini for (i=0,stl=0;i<nr;i++) { 3045e3038f0Sstefano_zampini Mat usedmat; 3055e3038f0Sstefano_zampini Mat_IS *matis; 3065e3038f0Sstefano_zampini const PetscInt *idxs; 3075e3038f0Sstefano_zampini 3085e3038f0Sstefano_zampini /* local IS for local NEST */ 3095b003df0Sstefano_zampini ierr = ISCreateStride(PETSC_COMM_SELF,lr[i],stl,1,&islrow[i]);CHKERRQ(ierr); 3105e3038f0Sstefano_zampini 3115e3038f0Sstefano_zampini /* l2gmap */ 3125e3038f0Sstefano_zampini j = 0; 3135e3038f0Sstefano_zampini usedmat = nest[i][j]; 3145e3038f0Sstefano_zampini while (!usedmat && j < nc) usedmat = nest[i][j++]; 31582d73161Sstefano_zampini ierr = MatISSetUpSF(usedmat);CHKERRQ(ierr); 3165e3038f0Sstefano_zampini matis = (Mat_IS*)(usedmat->data); 3175e3038f0Sstefano_zampini ierr = ISGetIndices(isrow[i],&idxs);CHKERRQ(ierr); 3185e3038f0Sstefano_zampini ierr = PetscSFBcastBegin(matis->sf,MPIU_INT,idxs,l2gidxs+stl);CHKERRQ(ierr); 3195e3038f0Sstefano_zampini ierr = PetscSFBcastEnd(matis->sf,MPIU_INT,idxs,l2gidxs+stl);CHKERRQ(ierr); 3205e3038f0Sstefano_zampini ierr = ISRestoreIndices(isrow[i],&idxs);CHKERRQ(ierr); 3215e3038f0Sstefano_zampini stl += lr[i]; 3225e3038f0Sstefano_zampini } 3235e3038f0Sstefano_zampini ierr = ISLocalToGlobalMappingCreate(comm,1,stl,l2gidxs,PETSC_OWN_POINTER,&rl2g);CHKERRQ(ierr); 3245e3038f0Sstefano_zampini 3255e3038f0Sstefano_zampini /* Create l2g map for columns of the new matrix and index sets for the local MATNEST */ 3265e3038f0Sstefano_zampini for (i=0,stl=0;i<nc;i++) stl += lc[i]; 3275e3038f0Sstefano_zampini ierr = PetscMalloc1(stl,&l2gidxs);CHKERRQ(ierr); 3285b003df0Sstefano_zampini for (i=0,stl=0;i<nc;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,lc[i],stl,1,&islcol[i]);CHKERRQ(ierr); 3355e3038f0Sstefano_zampini 3365e3038f0Sstefano_zampini /* l2gmap */ 3375e3038f0Sstefano_zampini j = 0; 3385e3038f0Sstefano_zampini usedmat = nest[j][i]; 3395e3038f0Sstefano_zampini while (!usedmat && j < nr) usedmat = nest[j++][i]; 34082d73161Sstefano_zampini ierr = MatISSetUpSF(usedmat);CHKERRQ(ierr); 3415e3038f0Sstefano_zampini matis = (Mat_IS*)(usedmat->data); 3425e3038f0Sstefano_zampini ierr = ISGetIndices(iscol[i],&idxs);CHKERRQ(ierr); 3435e3038f0Sstefano_zampini ierr = PetscSFBcastBegin(matis->csf,MPIU_INT,idxs,l2gidxs+stl);CHKERRQ(ierr); 3445e3038f0Sstefano_zampini ierr = PetscSFBcastEnd(matis->csf,MPIU_INT,idxs,l2gidxs+stl);CHKERRQ(ierr); 3455e3038f0Sstefano_zampini ierr = ISRestoreIndices(iscol[i],&idxs);CHKERRQ(ierr); 3465e3038f0Sstefano_zampini stl += lc[i]; 3475e3038f0Sstefano_zampini } 3485e3038f0Sstefano_zampini ierr = ISLocalToGlobalMappingCreate(comm,1,stl,l2gidxs,PETSC_OWN_POINTER,&cl2g);CHKERRQ(ierr); 3495e3038f0Sstefano_zampini 3505e3038f0Sstefano_zampini /* Create MATIS */ 3515e3038f0Sstefano_zampini ierr = MatCreate(comm,&B);CHKERRQ(ierr); 3525e3038f0Sstefano_zampini ierr = MatSetSizes(B,A->rmap->n,A->cmap->n,A->rmap->N,A->cmap->N);CHKERRQ(ierr); 3535e3038f0Sstefano_zampini ierr = MatGetBlockSizes(A,&rbs,&cbs);CHKERRQ(ierr); 3545e3038f0Sstefano_zampini ierr = MatSetBlockSizes(B,rbs,cbs);CHKERRQ(ierr); 3555e3038f0Sstefano_zampini ierr = MatSetType(B,MATIS);CHKERRQ(ierr); 3565e3038f0Sstefano_zampini ierr = MatSetLocalToGlobalMapping(B,rl2g,cl2g);CHKERRQ(ierr); 3575e3038f0Sstefano_zampini ierr = ISLocalToGlobalMappingDestroy(&rl2g);CHKERRQ(ierr); 3585e3038f0Sstefano_zampini ierr = ISLocalToGlobalMappingDestroy(&cl2g);CHKERRQ(ierr); 3595e3038f0Sstefano_zampini ierr = MatCreateNest(PETSC_COMM_SELF,nr,islrow,nc,islcol,snest,&lA);CHKERRQ(ierr); 3605e3038f0Sstefano_zampini ierr = MatISSetLocalMat(B,lA);CHKERRQ(ierr); 3615e3038f0Sstefano_zampini ierr = MatDestroy(&lA);CHKERRQ(ierr); 3625e3038f0Sstefano_zampini ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3635e3038f0Sstefano_zampini ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3645e3038f0Sstefano_zampini if (reuse == MAT_INPLACE_MATRIX) { 3655e3038f0Sstefano_zampini ierr = MatHeaderReplace(A,&B);CHKERRQ(ierr); 3665e3038f0Sstefano_zampini } else { 3675e3038f0Sstefano_zampini *newmat = B; 3685e3038f0Sstefano_zampini } 3695e3038f0Sstefano_zampini } else { 3705e3038f0Sstefano_zampini if (lreuse) { 3715e3038f0Sstefano_zampini ierr = MatISGetLocalMat(*newmat,&lA);CHKERRQ(ierr); 3725e3038f0Sstefano_zampini for (i=0;i<nr;i++) { 3735e3038f0Sstefano_zampini for (j=0;j<nc;j++) { 3745e3038f0Sstefano_zampini if (snest[i*nc+j]) { 3755e3038f0Sstefano_zampini ierr = MatNestSetSubMat(lA,i,j,snest[i*nc+j]);CHKERRQ(ierr); 3765e3038f0Sstefano_zampini } 3775e3038f0Sstefano_zampini } 3785e3038f0Sstefano_zampini } 3795e3038f0Sstefano_zampini } else { 3805b003df0Sstefano_zampini PetscInt stl; 3815b003df0Sstefano_zampini for (i=0,stl=0;i<nr;i++) { 3825b003df0Sstefano_zampini ierr = ISCreateStride(PETSC_COMM_SELF,lr[i],stl,1,&islrow[i]);CHKERRQ(ierr); 3835b003df0Sstefano_zampini stl += lr[i]; 3845e3038f0Sstefano_zampini } 3855b003df0Sstefano_zampini for (i=0,stl=0;i<nc;i++) { 3865b003df0Sstefano_zampini ierr = ISCreateStride(PETSC_COMM_SELF,lc[i],stl,1,&islcol[i]);CHKERRQ(ierr); 3875b003df0Sstefano_zampini stl += lc[i]; 3885e3038f0Sstefano_zampini } 3895e3038f0Sstefano_zampini ierr = MatCreateNest(PETSC_COMM_SELF,nr,islrow,nc,islcol,snest,&lA);CHKERRQ(ierr); 3905e3038f0Sstefano_zampini ierr = MatISSetLocalMat(*newmat,lA);CHKERRQ(ierr); 3915e3038f0Sstefano_zampini ierr = MatDestroy(&lA);CHKERRQ(ierr); 3925e3038f0Sstefano_zampini } 3935e3038f0Sstefano_zampini ierr = MatAssemblyBegin(*newmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3945e3038f0Sstefano_zampini ierr = MatAssemblyEnd(*newmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3955e3038f0Sstefano_zampini } 3965e3038f0Sstefano_zampini 3975b003df0Sstefano_zampini /* Create local matrix in MATNEST format */ 3985b003df0Sstefano_zampini convert = PETSC_FALSE; 3995b003df0Sstefano_zampini ierr = PetscOptionsGetBool(NULL,((PetscObject)A)->prefix,"-matis_convert_local_nest",&convert,NULL);CHKERRQ(ierr); 4005b003df0Sstefano_zampini if (convert) { 4015b003df0Sstefano_zampini Mat M; 4025b003df0Sstefano_zampini MatISLocalFields lf; 4035b003df0Sstefano_zampini PetscContainer c; 4045b003df0Sstefano_zampini 4055b003df0Sstefano_zampini ierr = MatISGetLocalMat(*newmat,&lA);CHKERRQ(ierr); 4065b003df0Sstefano_zampini ierr = MatConvert(lA,MATAIJ,MAT_INITIAL_MATRIX,&M);CHKERRQ(ierr); 4075b003df0Sstefano_zampini ierr = MatISSetLocalMat(*newmat,M);CHKERRQ(ierr); 4085b003df0Sstefano_zampini ierr = MatDestroy(&M);CHKERRQ(ierr); 4095b003df0Sstefano_zampini 4105b003df0Sstefano_zampini /* attach local fields to the matrix */ 4115b003df0Sstefano_zampini ierr = PetscNew(&lf);CHKERRQ(ierr); 4125b003df0Sstefano_zampini ierr = PetscCalloc2(nr,&lf->rf,nc,&lf->cf);CHKERRQ(ierr); 4135b003df0Sstefano_zampini for (i=0;i<nr;i++) { 4145b003df0Sstefano_zampini PetscInt n,st; 4155b003df0Sstefano_zampini 4165b003df0Sstefano_zampini ierr = ISGetLocalSize(islrow[i],&n);CHKERRQ(ierr); 4175b003df0Sstefano_zampini ierr = ISStrideGetInfo(islrow[i],&st,NULL);CHKERRQ(ierr); 4185b003df0Sstefano_zampini ierr = ISCreateStride(comm,n,st,1,&lf->rf[i]);CHKERRQ(ierr); 4195b003df0Sstefano_zampini } 4205b003df0Sstefano_zampini for (i=0;i<nc;i++) { 4215b003df0Sstefano_zampini PetscInt n,st; 4225b003df0Sstefano_zampini 4235b003df0Sstefano_zampini ierr = ISGetLocalSize(islcol[i],&n);CHKERRQ(ierr); 4245b003df0Sstefano_zampini ierr = ISStrideGetInfo(islcol[i],&st,NULL);CHKERRQ(ierr); 4255b003df0Sstefano_zampini ierr = ISCreateStride(comm,n,st,1,&lf->cf[i]);CHKERRQ(ierr); 4265b003df0Sstefano_zampini } 4275b003df0Sstefano_zampini lf->nr = nr; 4285b003df0Sstefano_zampini lf->nc = nc; 4295b003df0Sstefano_zampini ierr = PetscContainerCreate(PetscObjectComm((PetscObject)(*newmat)),&c);CHKERRQ(ierr); 4305b003df0Sstefano_zampini ierr = PetscContainerSetPointer(c,lf);CHKERRQ(ierr); 4315b003df0Sstefano_zampini ierr = PetscContainerSetUserDestroy(c,MatISContainerDestroyFields_Private);CHKERRQ(ierr); 4325b003df0Sstefano_zampini ierr = PetscObjectCompose((PetscObject)(*newmat),"_convert_nest_lfields",(PetscObject)c);CHKERRQ(ierr); 4335b003df0Sstefano_zampini ierr = PetscContainerDestroy(&c);CHKERRQ(ierr); 4345b003df0Sstefano_zampini } 4355b003df0Sstefano_zampini 4365e3038f0Sstefano_zampini /* Free workspace */ 4375e3038f0Sstefano_zampini for (i=0;i<nr;i++) { 4385e3038f0Sstefano_zampini ierr = ISDestroy(&islrow[i]);CHKERRQ(ierr); 4395e3038f0Sstefano_zampini } 4405e3038f0Sstefano_zampini for (i=0;i<nc;i++) { 4415e3038f0Sstefano_zampini ierr = ISDestroy(&islcol[i]);CHKERRQ(ierr); 4425e3038f0Sstefano_zampini } 4435e3038f0Sstefano_zampini ierr = PetscFree5(isrow,iscol,islrow,islcol,snest);CHKERRQ(ierr); 4445b003df0Sstefano_zampini ierr = PetscFree2(lr,lc);CHKERRQ(ierr); 4455e3038f0Sstefano_zampini PetscFunctionReturn(0); 4465e3038f0Sstefano_zampini } 4475e3038f0Sstefano_zampini 4485e3038f0Sstefano_zampini #undef __FUNCT__ 449d7f69cd0SStefano Zampini #define __FUNCT__ "MatTranspose_IS" 450d7f69cd0SStefano Zampini PetscErrorCode MatTranspose_IS(Mat A,MatReuse reuse,Mat *B) 451d7f69cd0SStefano Zampini { 452d7f69cd0SStefano Zampini Mat C,lC,lA; 453d7f69cd0SStefano Zampini ISLocalToGlobalMapping rl2g,cl2g; 454d7f69cd0SStefano Zampini PetscBool notset = PETSC_FALSE,cong = PETSC_TRUE; 455d7f69cd0SStefano Zampini PetscErrorCode ierr; 456d7f69cd0SStefano Zampini 457d7f69cd0SStefano Zampini PetscFunctionBegin; 458d7f69cd0SStefano Zampini if (reuse == MAT_REUSE_MATRIX) { 459d7f69cd0SStefano Zampini PetscBool rcong,ccong; 460d7f69cd0SStefano Zampini 461d7f69cd0SStefano Zampini ierr = PetscLayoutCompare((*B)->cmap,A->rmap,&rcong);CHKERRQ(ierr); 462d7f69cd0SStefano Zampini ierr = PetscLayoutCompare((*B)->rmap,A->cmap,&ccong);CHKERRQ(ierr); 463fa520230SStefano Zampini cong = (PetscBool)(rcong || ccong); 464d7f69cd0SStefano Zampini } 465d7f69cd0SStefano Zampini if (reuse == MAT_INITIAL_MATRIX || *B == A || !cong) { 466d7f69cd0SStefano Zampini ierr = MatCreate(PetscObjectComm((PetscObject)A),&C);CHKERRQ(ierr); 467d7f69cd0SStefano Zampini } else { 468d7f69cd0SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)*B,MATIS,¬set);CHKERRQ(ierr); 469d7f69cd0SStefano Zampini C = *B; 470d7f69cd0SStefano Zampini } 471d7f69cd0SStefano Zampini 472d7f69cd0SStefano Zampini if (!notset) { 473d7f69cd0SStefano Zampini ierr = MatSetSizes(C,A->cmap->n,A->rmap->n,A->cmap->N,A->rmap->N);CHKERRQ(ierr); 474d7f69cd0SStefano Zampini ierr = MatSetBlockSizes(C,PetscAbs(A->cmap->bs),PetscAbs(A->rmap->bs));CHKERRQ(ierr); 475d7f69cd0SStefano Zampini ierr = MatSetType(C,MATIS);CHKERRQ(ierr); 476d7f69cd0SStefano Zampini ierr = MatGetLocalToGlobalMapping(A,&rl2g,&cl2g);CHKERRQ(ierr); 477d7f69cd0SStefano Zampini ierr = MatSetLocalToGlobalMapping(C,cl2g,rl2g);CHKERRQ(ierr); 478d7f69cd0SStefano Zampini } 479d7f69cd0SStefano Zampini 480d7f69cd0SStefano Zampini /* perform local transposition */ 481d7f69cd0SStefano Zampini ierr = MatISGetLocalMat(A,&lA);CHKERRQ(ierr); 482d7f69cd0SStefano Zampini ierr = MatTranspose(lA,MAT_INITIAL_MATRIX,&lC);CHKERRQ(ierr); 483d7f69cd0SStefano Zampini ierr = MatISSetLocalMat(C,lC);CHKERRQ(ierr); 484d7f69cd0SStefano Zampini ierr = MatDestroy(&lC);CHKERRQ(ierr); 485d7f69cd0SStefano Zampini 486d7f69cd0SStefano Zampini ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 487d7f69cd0SStefano Zampini ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 488d7f69cd0SStefano Zampini 489d7f69cd0SStefano Zampini if (reuse == MAT_INITIAL_MATRIX || *B != A) { 490d7f69cd0SStefano Zampini if (!cong) { 491d7f69cd0SStefano Zampini ierr = MatDestroy(B);CHKERRQ(ierr); 492d7f69cd0SStefano Zampini } 493d7f69cd0SStefano Zampini *B = C; 494d7f69cd0SStefano Zampini } else { 495d7f69cd0SStefano Zampini ierr = MatHeaderMerge(A,&C);CHKERRQ(ierr); 496d7f69cd0SStefano Zampini } 497d7f69cd0SStefano Zampini PetscFunctionReturn(0); 498d7f69cd0SStefano Zampini } 499d7f69cd0SStefano Zampini 500d7f69cd0SStefano Zampini #undef __FUNCT__ 5013fd1c9e7SStefano Zampini #define __FUNCT__ "MatDiagonalSet_IS" 5023fd1c9e7SStefano Zampini PetscErrorCode MatDiagonalSet_IS(Mat A,Vec D,InsertMode insmode) 5033fd1c9e7SStefano Zampini { 5043fd1c9e7SStefano Zampini Mat_IS *is = (Mat_IS*)A->data; 5053fd1c9e7SStefano Zampini PetscErrorCode ierr; 5063fd1c9e7SStefano Zampini 5073fd1c9e7SStefano Zampini PetscFunctionBegin; 5083fd1c9e7SStefano Zampini if (!D) { /* this code branch is used by MatShift_IS */ 5093fd1c9e7SStefano Zampini ierr = VecSet(is->y,1.);CHKERRQ(ierr); 5103fd1c9e7SStefano Zampini } else { 5113fd1c9e7SStefano Zampini ierr = VecScatterBegin(is->rctx,D,is->y,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 5123fd1c9e7SStefano Zampini ierr = VecScatterEnd(is->rctx,D,is->y,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 5133fd1c9e7SStefano Zampini } 5143fd1c9e7SStefano Zampini ierr = VecPointwiseDivide(is->y,is->y,is->counter);CHKERRQ(ierr); 5153fd1c9e7SStefano Zampini ierr = MatDiagonalSet(is->A,is->y,insmode);CHKERRQ(ierr); 5163fd1c9e7SStefano Zampini PetscFunctionReturn(0); 5173fd1c9e7SStefano Zampini } 5183fd1c9e7SStefano Zampini 5193fd1c9e7SStefano Zampini #undef __FUNCT__ 5203fd1c9e7SStefano Zampini #define __FUNCT__ "MatShift_IS" 5213fd1c9e7SStefano Zampini PetscErrorCode MatShift_IS(Mat A,PetscScalar a) 5223fd1c9e7SStefano Zampini { 5233fd1c9e7SStefano Zampini PetscErrorCode ierr; 5243fd1c9e7SStefano Zampini 5253fd1c9e7SStefano Zampini PetscFunctionBegin; 5263fd1c9e7SStefano Zampini ierr = MatDiagonalSet_IS(A,NULL,ADD_VALUES);CHKERRQ(ierr); 5273fd1c9e7SStefano Zampini PetscFunctionReturn(0); 5283fd1c9e7SStefano Zampini } 5293fd1c9e7SStefano Zampini 5303fd1c9e7SStefano Zampini #undef __FUNCT__ 531f26d0771SStefano Zampini #define __FUNCT__ "MatSetValuesLocal_SubMat_IS" 532f26d0771SStefano Zampini static PetscErrorCode MatSetValuesLocal_SubMat_IS(Mat A,PetscInt m,const PetscInt *rows, PetscInt n,const PetscInt *cols,const PetscScalar *values,InsertMode addv) 533f26d0771SStefano Zampini { 534f26d0771SStefano Zampini PetscErrorCode ierr; 535f26d0771SStefano Zampini Mat_IS *is = (Mat_IS*)A->data; 536f26d0771SStefano Zampini PetscInt rows_l[MATIS_MAX_ENTRIES_INSERTION],cols_l[MATIS_MAX_ENTRIES_INSERTION]; 537f26d0771SStefano Zampini 538f26d0771SStefano Zampini PetscFunctionBegin; 539f26d0771SStefano Zampini #if defined(PETSC_USE_DEBUG) 540f26d0771SStefano 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); 541f26d0771SStefano Zampini #endif 542f26d0771SStefano Zampini ierr = ISLocalToGlobalMappingApply(A->rmap->mapping,m,rows,rows_l);CHKERRQ(ierr); 543f26d0771SStefano Zampini ierr = ISLocalToGlobalMappingApply(A->cmap->mapping,n,cols,cols_l);CHKERRQ(ierr); 544f26d0771SStefano Zampini ierr = MatSetValues(is->A,m,rows_l,n,cols_l,values,addv);CHKERRQ(ierr); 545f26d0771SStefano Zampini PetscFunctionReturn(0); 546f26d0771SStefano Zampini } 547f26d0771SStefano Zampini 548f26d0771SStefano Zampini #undef __FUNCT__ 549f26d0771SStefano Zampini #define __FUNCT__ "MatSetValuesBlockedLocal_SubMat_IS" 550f26d0771SStefano Zampini static PetscErrorCode MatSetValuesBlockedLocal_SubMat_IS(Mat A,PetscInt m,const PetscInt *rows, PetscInt n,const PetscInt *cols,const PetscScalar *values,InsertMode addv) 551f26d0771SStefano Zampini { 552f26d0771SStefano Zampini PetscErrorCode ierr; 553f26d0771SStefano Zampini Mat_IS *is = (Mat_IS*)A->data; 554f26d0771SStefano Zampini PetscInt rows_l[MATIS_MAX_ENTRIES_INSERTION],cols_l[MATIS_MAX_ENTRIES_INSERTION]; 555f26d0771SStefano Zampini 556f26d0771SStefano Zampini PetscFunctionBegin; 557f26d0771SStefano Zampini #if defined(PETSC_USE_DEBUG) 558f26d0771SStefano 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); 559f26d0771SStefano Zampini #endif 560f26d0771SStefano Zampini ierr = ISLocalToGlobalMappingApplyBlock(A->rmap->mapping,m,rows,rows_l);CHKERRQ(ierr); 561f26d0771SStefano Zampini ierr = ISLocalToGlobalMappingApplyBlock(A->cmap->mapping,n,cols,cols_l);CHKERRQ(ierr); 562f26d0771SStefano Zampini ierr = MatSetValuesBlocked(is->A,m,rows_l,n,cols_l,values,addv);CHKERRQ(ierr); 563f26d0771SStefano Zampini PetscFunctionReturn(0); 564f26d0771SStefano Zampini } 565f26d0771SStefano Zampini 566f26d0771SStefano Zampini #undef __FUNCT__ 567a8116848SStefano Zampini #define __FUNCT__ "PetscLayoutMapLocal_Private" 568f0ae7da4SStefano Zampini static PetscErrorCode PetscLayoutMapLocal_Private(PetscLayout map,PetscInt N,const PetscInt idxs[], PetscInt *on,PetscInt **oidxs,PetscInt **ogidxs) 569a8116848SStefano Zampini { 570a8116848SStefano Zampini PetscInt *owners = map->range; 571a8116848SStefano Zampini PetscInt n = map->n; 572a8116848SStefano Zampini PetscSF sf; 573a8116848SStefano Zampini PetscInt *lidxs,*work = NULL; 574a8116848SStefano Zampini PetscSFNode *ridxs; 575a8116848SStefano Zampini PetscMPIInt rank; 576a8116848SStefano Zampini PetscInt r, p = 0, len = 0; 577a8116848SStefano Zampini PetscErrorCode ierr; 578a8116848SStefano Zampini 579a8116848SStefano Zampini PetscFunctionBegin; 580a8116848SStefano Zampini /* Create SF where leaves are input idxs and roots are owned idxs (code adapted from MatZeroRowsMapLocal_Private) */ 581a8116848SStefano Zampini ierr = MPI_Comm_rank(map->comm,&rank);CHKERRQ(ierr); 582a8116848SStefano Zampini ierr = PetscMalloc1(n,&lidxs);CHKERRQ(ierr); 583a8116848SStefano Zampini for (r = 0; r < n; ++r) lidxs[r] = -1; 584a8116848SStefano Zampini ierr = PetscMalloc1(N,&ridxs);CHKERRQ(ierr); 585a8116848SStefano Zampini for (r = 0; r < N; ++r) { 586a8116848SStefano Zampini const PetscInt idx = idxs[r]; 587a8116848SStefano 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); 588a8116848SStefano Zampini if (idx < owners[p] || owners[p+1] <= idx) { /* short-circuit the search if the last p owns this idx too */ 589a8116848SStefano Zampini ierr = PetscLayoutFindOwner(map,idx,&p);CHKERRQ(ierr); 590a8116848SStefano Zampini } 591a8116848SStefano Zampini ridxs[r].rank = p; 592a8116848SStefano Zampini ridxs[r].index = idxs[r] - owners[p]; 593a8116848SStefano Zampini } 594a8116848SStefano Zampini ierr = PetscSFCreate(map->comm,&sf);CHKERRQ(ierr); 595a8116848SStefano Zampini ierr = PetscSFSetGraph(sf,n,N,NULL,PETSC_OWN_POINTER,ridxs,PETSC_OWN_POINTER);CHKERRQ(ierr); 596a8116848SStefano Zampini ierr = PetscSFReduceBegin(sf,MPIU_INT,(PetscInt*)idxs,lidxs,MPI_LOR);CHKERRQ(ierr); 597a8116848SStefano Zampini ierr = PetscSFReduceEnd(sf,MPIU_INT,(PetscInt*)idxs,lidxs,MPI_LOR);CHKERRQ(ierr); 598f0ae7da4SStefano Zampini if (ogidxs) { /* communicate global idxs */ 599a8116848SStefano Zampini PetscInt cum = 0,start,*work2; 600f0ae7da4SStefano Zampini 601f0ae7da4SStefano Zampini ierr = PetscMalloc1(n,&work);CHKERRQ(ierr); 602a8116848SStefano Zampini ierr = PetscCalloc1(N,&work2);CHKERRQ(ierr); 603a8116848SStefano Zampini for (r = 0; r < N; ++r) if (idxs[r] >=0) cum++; 604a8116848SStefano Zampini ierr = MPI_Scan(&cum,&start,1,MPIU_INT,MPI_SUM,map->comm);CHKERRQ(ierr); 605a8116848SStefano Zampini start -= cum; 606a8116848SStefano Zampini cum = 0; 607a8116848SStefano Zampini for (r = 0; r < N; ++r) if (idxs[r] >=0) work2[r] = start+cum++; 608a8116848SStefano Zampini ierr = PetscSFReduceBegin(sf,MPIU_INT,work2,work,MPIU_REPLACE);CHKERRQ(ierr); 609a8116848SStefano Zampini ierr = PetscSFReduceEnd(sf,MPIU_INT,work2,work,MPIU_REPLACE);CHKERRQ(ierr); 610a8116848SStefano Zampini ierr = PetscFree(work2);CHKERRQ(ierr); 611a8116848SStefano Zampini } 612a8116848SStefano Zampini ierr = PetscSFDestroy(&sf);CHKERRQ(ierr); 613a8116848SStefano Zampini /* Compress and put in indices */ 614a8116848SStefano Zampini for (r = 0; r < n; ++r) 615a8116848SStefano Zampini if (lidxs[r] >= 0) { 616a8116848SStefano Zampini if (work) work[len] = work[r]; 617a8116848SStefano Zampini lidxs[len++] = r; 618a8116848SStefano Zampini } 619a8116848SStefano Zampini if (on) *on = len; 620a8116848SStefano Zampini if (oidxs) *oidxs = lidxs; 621a8116848SStefano Zampini if (ogidxs) *ogidxs = work; 622a8116848SStefano Zampini PetscFunctionReturn(0); 623a8116848SStefano Zampini } 624a8116848SStefano Zampini 625a8116848SStefano Zampini #undef __FUNCT__ 626a8116848SStefano Zampini #define __FUNCT__ "MatGetSubMatrix_IS" 627a8116848SStefano Zampini static PetscErrorCode MatGetSubMatrix_IS(Mat mat,IS irow,IS icol,MatReuse scall,Mat *newmat) 628a8116848SStefano Zampini { 629a8116848SStefano Zampini Mat locmat,newlocmat; 630a8116848SStefano Zampini Mat_IS *newmatis; 631a8116848SStefano Zampini #if defined(PETSC_USE_DEBUG) 632a8116848SStefano Zampini Vec rtest,ltest; 633a8116848SStefano Zampini const PetscScalar *array; 634a8116848SStefano Zampini #endif 635a8116848SStefano Zampini const PetscInt *idxs; 636a8116848SStefano Zampini PetscInt i,m,n; 637a8116848SStefano Zampini PetscErrorCode ierr; 638a8116848SStefano Zampini 639a8116848SStefano Zampini PetscFunctionBegin; 640a8116848SStefano Zampini if (scall == MAT_REUSE_MATRIX) { 641a8116848SStefano Zampini PetscBool ismatis; 642a8116848SStefano Zampini 643a8116848SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)*newmat,MATIS,&ismatis);CHKERRQ(ierr); 644a8116848SStefano Zampini if (!ismatis) SETERRQ(PetscObjectComm((PetscObject)*newmat),PETSC_ERR_ARG_WRONG,"Cannot reuse matrix! Not of MATIS type"); 645a8116848SStefano Zampini newmatis = (Mat_IS*)(*newmat)->data; 646a8116848SStefano Zampini if (!newmatis->getsub_ris) SETERRQ(PetscObjectComm((PetscObject)*newmat),PETSC_ERR_ARG_WRONG,"Cannot reuse matrix! Misses local row IS"); 647a8116848SStefano Zampini if (!newmatis->getsub_cis) SETERRQ(PetscObjectComm((PetscObject)*newmat),PETSC_ERR_ARG_WRONG,"Cannot reuse matrix! Misses local col IS"); 648a8116848SStefano Zampini } 649a8116848SStefano Zampini /* irow and icol may not have duplicate entries */ 650a8116848SStefano Zampini #if defined(PETSC_USE_DEBUG) 651a8116848SStefano Zampini ierr = MatCreateVecs(mat,<est,&rtest);CHKERRQ(ierr); 652a8116848SStefano Zampini ierr = ISGetLocalSize(irow,&n);CHKERRQ(ierr); 653a8116848SStefano Zampini ierr = ISGetIndices(irow,&idxs);CHKERRQ(ierr); 654a8116848SStefano Zampini for (i=0;i<n;i++) { 655a8116848SStefano Zampini ierr = VecSetValue(rtest,idxs[i],1.0,ADD_VALUES);CHKERRQ(ierr); 656a8116848SStefano Zampini } 657a8116848SStefano Zampini ierr = VecAssemblyBegin(rtest);CHKERRQ(ierr); 658a8116848SStefano Zampini ierr = VecAssemblyEnd(rtest);CHKERRQ(ierr); 659a8116848SStefano Zampini ierr = VecGetLocalSize(rtest,&n);CHKERRQ(ierr); 660a8116848SStefano Zampini ierr = VecGetOwnershipRange(rtest,&m,NULL);CHKERRQ(ierr); 661a8116848SStefano Zampini ierr = VecGetArrayRead(rtest,&array);CHKERRQ(ierr); 662fd479f66SMatthew G. Knepley for (i=0;i<n;i++) if (array[i] != 0. && array[i] != 1.) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_SUP,"Index %D counted %D times! Irow may not have duplicate entries",i+m,(PetscInt)PetscRealPart(array[i])); 663a8116848SStefano Zampini ierr = VecRestoreArrayRead(rtest,&array);CHKERRQ(ierr); 664a8116848SStefano Zampini ierr = ISRestoreIndices(irow,&idxs);CHKERRQ(ierr); 665a8116848SStefano Zampini ierr = ISGetLocalSize(icol,&n);CHKERRQ(ierr); 666a8116848SStefano Zampini ierr = ISGetIndices(icol,&idxs);CHKERRQ(ierr); 667a8116848SStefano Zampini for (i=0;i<n;i++) { 668a8116848SStefano Zampini ierr = VecSetValue(ltest,idxs[i],1.0,ADD_VALUES);CHKERRQ(ierr); 669a8116848SStefano Zampini } 670a8116848SStefano Zampini ierr = VecAssemblyBegin(ltest);CHKERRQ(ierr); 671a8116848SStefano Zampini ierr = VecAssemblyEnd(ltest);CHKERRQ(ierr); 672a8116848SStefano Zampini ierr = VecGetLocalSize(ltest,&n);CHKERRQ(ierr); 673a8116848SStefano Zampini ierr = VecGetOwnershipRange(ltest,&m,NULL);CHKERRQ(ierr); 674a8116848SStefano Zampini ierr = VecGetArrayRead(ltest,&array);CHKERRQ(ierr); 675fd479f66SMatthew G. Knepley for (i=0;i<n;i++) if (array[i] != 0. && array[i] != 1.) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_SUP,"Index %D counted %D times! Icol may not have duplicate entries",i+m,(PetscInt)PetscRealPart(array[i])); 676a8116848SStefano Zampini ierr = VecRestoreArrayRead(ltest,&array);CHKERRQ(ierr); 677a8116848SStefano Zampini ierr = ISRestoreIndices(icol,&idxs);CHKERRQ(ierr); 678a8116848SStefano Zampini ierr = VecDestroy(&rtest);CHKERRQ(ierr); 679a8116848SStefano Zampini ierr = VecDestroy(<est);CHKERRQ(ierr); 680a8116848SStefano Zampini #endif 681a8116848SStefano Zampini if (scall == MAT_INITIAL_MATRIX) { 682a8116848SStefano Zampini Mat_IS *matis = (Mat_IS*)mat->data; 683a8116848SStefano Zampini ISLocalToGlobalMapping rl2g; 684a8116848SStefano Zampini IS is; 685a8116848SStefano Zampini PetscInt *lidxs,*lgidxs,*newgidxs; 6866dd40735SStefano Zampini PetscInt ll,newloc; 687a8116848SStefano Zampini MPI_Comm comm; 688a8116848SStefano Zampini 689a8116848SStefano Zampini ierr = PetscObjectGetComm((PetscObject)mat,&comm);CHKERRQ(ierr); 690a8116848SStefano Zampini ierr = ISGetLocalSize(irow,&m);CHKERRQ(ierr); 691a8116848SStefano Zampini ierr = ISGetLocalSize(icol,&n);CHKERRQ(ierr); 692a8116848SStefano Zampini ierr = MatCreate(comm,newmat);CHKERRQ(ierr); 693a8116848SStefano Zampini ierr = MatSetType(*newmat,MATIS);CHKERRQ(ierr); 694a8116848SStefano Zampini ierr = MatSetSizes(*newmat,m,n,PETSC_DECIDE,PETSC_DECIDE);CHKERRQ(ierr); 695a8116848SStefano Zampini /* communicate irow to their owners in the layout */ 696a8116848SStefano Zampini ierr = ISGetIndices(irow,&idxs);CHKERRQ(ierr); 697f0ae7da4SStefano Zampini ierr = PetscLayoutMapLocal_Private(mat->rmap,m,idxs,&ll,&lidxs,&lgidxs);CHKERRQ(ierr); 698a8116848SStefano Zampini ierr = ISRestoreIndices(irow,&idxs);CHKERRQ(ierr); 6993d996552SStefano Zampini ierr = MatISSetUpSF(mat);CHKERRQ(ierr); 7003d996552SStefano Zampini ierr = PetscMemzero(matis->sf_rootdata,matis->sf->nroots*sizeof(PetscInt));CHKERRQ(ierr); 701a8116848SStefano Zampini for (i=0;i<ll;i++) matis->sf_rootdata[lidxs[i]] = lgidxs[i]+1; 702a8116848SStefano Zampini ierr = PetscFree(lidxs);CHKERRQ(ierr); 703a8116848SStefano Zampini ierr = PetscFree(lgidxs);CHKERRQ(ierr); 704a8116848SStefano Zampini ierr = PetscSFBcastBegin(matis->sf,MPIU_INT,matis->sf_rootdata,matis->sf_leafdata);CHKERRQ(ierr); 705a8116848SStefano Zampini ierr = PetscSFBcastEnd(matis->sf,MPIU_INT,matis->sf_rootdata,matis->sf_leafdata);CHKERRQ(ierr); 7063d996552SStefano Zampini for (i=0,newloc=0;i<matis->sf->nleaves;i++) if (matis->sf_leafdata[i]) newloc++; 707a8116848SStefano Zampini ierr = PetscMalloc1(newloc,&newgidxs);CHKERRQ(ierr); 708a8116848SStefano Zampini ierr = PetscMalloc1(newloc,&lidxs);CHKERRQ(ierr); 7093d996552SStefano Zampini for (i=0,newloc=0;i<matis->sf->nleaves;i++) 710a8116848SStefano Zampini if (matis->sf_leafdata[i]) { 711a8116848SStefano Zampini lidxs[newloc] = i; 712a8116848SStefano Zampini newgidxs[newloc++] = matis->sf_leafdata[i]-1; 713a8116848SStefano Zampini } 714a8116848SStefano Zampini ierr = ISCreateGeneral(comm,newloc,newgidxs,PETSC_OWN_POINTER,&is);CHKERRQ(ierr); 715a8116848SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is,&rl2g);CHKERRQ(ierr); 716a8116848SStefano Zampini ierr = ISDestroy(&is);CHKERRQ(ierr); 717a8116848SStefano Zampini /* local is to extract local submatrix */ 718a8116848SStefano Zampini newmatis = (Mat_IS*)(*newmat)->data; 719a8116848SStefano Zampini ierr = ISCreateGeneral(comm,newloc,lidxs,PETSC_OWN_POINTER,&newmatis->getsub_ris);CHKERRQ(ierr); 720a8116848SStefano Zampini if (mat->congruentlayouts == -1) { /* first time we compare rows and cols layouts */ 721a8116848SStefano Zampini PetscBool cong; 722a8116848SStefano Zampini ierr = PetscLayoutCompare(mat->rmap,mat->cmap,&cong);CHKERRQ(ierr); 723a8116848SStefano Zampini if (cong) mat->congruentlayouts = 1; 724a8116848SStefano Zampini else mat->congruentlayouts = 0; 725a8116848SStefano Zampini } 726a8116848SStefano Zampini if (mat->congruentlayouts && irow == icol) { 727a8116848SStefano Zampini ierr = MatSetLocalToGlobalMapping(*newmat,rl2g,rl2g);CHKERRQ(ierr); 728a8116848SStefano Zampini ierr = PetscObjectReference((PetscObject)newmatis->getsub_ris);CHKERRQ(ierr); 729a8116848SStefano Zampini newmatis->getsub_cis = newmatis->getsub_ris; 730a8116848SStefano Zampini } else { 731a8116848SStefano Zampini ISLocalToGlobalMapping cl2g; 732a8116848SStefano Zampini 733a8116848SStefano Zampini /* communicate icol to their owners in the layout */ 734a8116848SStefano Zampini ierr = ISGetIndices(icol,&idxs);CHKERRQ(ierr); 735f0ae7da4SStefano Zampini ierr = PetscLayoutMapLocal_Private(mat->cmap,n,idxs,&ll,&lidxs,&lgidxs);CHKERRQ(ierr); 736a8116848SStefano Zampini ierr = ISRestoreIndices(icol,&idxs);CHKERRQ(ierr); 7373d996552SStefano Zampini ierr = PetscMemzero(matis->csf_rootdata,matis->csf->nroots*sizeof(PetscInt));CHKERRQ(ierr); 738a8116848SStefano Zampini for (i=0;i<ll;i++) matis->csf_rootdata[lidxs[i]] = lgidxs[i]+1; 739a8116848SStefano Zampini ierr = PetscFree(lidxs);CHKERRQ(ierr); 740a8116848SStefano Zampini ierr = PetscFree(lgidxs);CHKERRQ(ierr); 741a8116848SStefano Zampini ierr = PetscSFBcastBegin(matis->csf,MPIU_INT,matis->csf_rootdata,matis->csf_leafdata);CHKERRQ(ierr); 742a8116848SStefano Zampini ierr = PetscSFBcastEnd(matis->csf,MPIU_INT,matis->csf_rootdata,matis->csf_leafdata);CHKERRQ(ierr); 7433d996552SStefano Zampini for (i=0,newloc=0;i<matis->csf->nleaves;i++) if (matis->csf_leafdata[i]) newloc++; 744a8116848SStefano Zampini ierr = PetscMalloc1(newloc,&newgidxs);CHKERRQ(ierr); 745a8116848SStefano Zampini ierr = PetscMalloc1(newloc,&lidxs);CHKERRQ(ierr); 7463d996552SStefano Zampini for (i=0,newloc=0;i<matis->csf->nleaves;i++) 747a8116848SStefano Zampini if (matis->csf_leafdata[i]) { 748a8116848SStefano Zampini lidxs[newloc] = i; 749a8116848SStefano Zampini newgidxs[newloc++] = matis->csf_leafdata[i]-1; 750a8116848SStefano Zampini } 751a8116848SStefano Zampini ierr = ISCreateGeneral(comm,newloc,newgidxs,PETSC_OWN_POINTER,&is);CHKERRQ(ierr); 752a8116848SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is,&cl2g);CHKERRQ(ierr); 753a8116848SStefano Zampini ierr = ISDestroy(&is);CHKERRQ(ierr); 754a8116848SStefano Zampini /* local is to extract local submatrix */ 755a8116848SStefano Zampini ierr = ISCreateGeneral(comm,newloc,lidxs,PETSC_OWN_POINTER,&newmatis->getsub_cis);CHKERRQ(ierr); 756a8116848SStefano Zampini ierr = MatSetLocalToGlobalMapping(*newmat,rl2g,cl2g);CHKERRQ(ierr); 757a8116848SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&cl2g);CHKERRQ(ierr); 758a8116848SStefano Zampini } 759a8116848SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&rl2g);CHKERRQ(ierr); 760a8116848SStefano Zampini } else { 761a8116848SStefano Zampini ierr = MatISGetLocalMat(*newmat,&newlocmat);CHKERRQ(ierr); 762a8116848SStefano Zampini } 763a8116848SStefano Zampini ierr = MatISGetLocalMat(mat,&locmat);CHKERRQ(ierr); 764a8116848SStefano Zampini newmatis = (Mat_IS*)(*newmat)->data; 765a8116848SStefano Zampini ierr = MatGetSubMatrix(locmat,newmatis->getsub_ris,newmatis->getsub_cis,scall,&newlocmat);CHKERRQ(ierr); 766a8116848SStefano Zampini if (scall == MAT_INITIAL_MATRIX) { 767a8116848SStefano Zampini ierr = MatISSetLocalMat(*newmat,newlocmat);CHKERRQ(ierr); 768a8116848SStefano Zampini ierr = MatDestroy(&newlocmat);CHKERRQ(ierr); 769a8116848SStefano Zampini } 770a8116848SStefano Zampini ierr = MatAssemblyBegin(*newmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 771a8116848SStefano Zampini ierr = MatAssemblyEnd(*newmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 772a8116848SStefano Zampini PetscFunctionReturn(0); 773a8116848SStefano Zampini } 774a8116848SStefano Zampini 775a8116848SStefano Zampini #undef __FUNCT__ 7762b404112SStefano Zampini #define __FUNCT__ "MatCopy_IS" 777a8116848SStefano Zampini static PetscErrorCode MatCopy_IS(Mat A,Mat B,MatStructure str) 7782b404112SStefano Zampini { 7792b404112SStefano Zampini Mat_IS *a = (Mat_IS*)A->data,*b; 7802b404112SStefano Zampini PetscBool ismatis; 7812b404112SStefano Zampini PetscErrorCode ierr; 7822b404112SStefano Zampini 7832b404112SStefano Zampini PetscFunctionBegin; 7842b404112SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)B,MATIS,&ismatis);CHKERRQ(ierr); 7852b404112SStefano Zampini if (!ismatis) SETERRQ(PetscObjectComm((PetscObject)B),PETSC_ERR_SUP,"Need to be implemented"); 7862b404112SStefano Zampini b = (Mat_IS*)B->data; 7872b404112SStefano Zampini ierr = MatCopy(a->A,b->A,str);CHKERRQ(ierr); 7882b404112SStefano Zampini PetscFunctionReturn(0); 7892b404112SStefano Zampini } 7902b404112SStefano Zampini 7912b404112SStefano Zampini #undef __FUNCT__ 7926bd84002SStefano Zampini #define __FUNCT__ "MatMissingDiagonal_IS" 793a8116848SStefano Zampini static PetscErrorCode MatMissingDiagonal_IS(Mat A,PetscBool *missing,PetscInt *d) 7946bd84002SStefano Zampini { 795527b2640SStefano Zampini Vec v; 796527b2640SStefano Zampini const PetscScalar *array; 797527b2640SStefano Zampini PetscInt i,n; 7986bd84002SStefano Zampini PetscErrorCode ierr; 7996bd84002SStefano Zampini 8006bd84002SStefano Zampini PetscFunctionBegin; 801527b2640SStefano Zampini *missing = PETSC_FALSE; 802527b2640SStefano Zampini ierr = MatCreateVecs(A,NULL,&v);CHKERRQ(ierr); 803527b2640SStefano Zampini ierr = MatGetDiagonal(A,v);CHKERRQ(ierr); 804527b2640SStefano Zampini ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr); 805527b2640SStefano Zampini ierr = VecGetArrayRead(v,&array);CHKERRQ(ierr); 806527b2640SStefano Zampini for (i=0;i<n;i++) if (array[i] == 0.) break; 807527b2640SStefano Zampini ierr = VecRestoreArrayRead(v,&array);CHKERRQ(ierr); 808527b2640SStefano Zampini ierr = VecDestroy(&v);CHKERRQ(ierr); 809527b2640SStefano Zampini if (i != n) *missing = PETSC_TRUE; 810527b2640SStefano Zampini if (d) { 811527b2640SStefano Zampini *d = -1; 812527b2640SStefano Zampini if (*missing) { 813527b2640SStefano Zampini PetscInt rstart; 814527b2640SStefano Zampini ierr = MatGetOwnershipRange(A,&rstart,NULL);CHKERRQ(ierr); 815527b2640SStefano Zampini *d = i+rstart; 816527b2640SStefano Zampini } 817527b2640SStefano Zampini } 8186bd84002SStefano Zampini PetscFunctionReturn(0); 8196bd84002SStefano Zampini } 8206bd84002SStefano Zampini 8216bd84002SStefano Zampini #undef __FUNCT__ 822cf0a3239SStefano Zampini #define __FUNCT__ "MatISSetUpSF_IS" 823cf0a3239SStefano Zampini static PetscErrorCode MatISSetUpSF_IS(Mat B) 82428f4e0baSStefano Zampini { 82528f4e0baSStefano Zampini Mat_IS *matis = (Mat_IS*)(B->data); 82628f4e0baSStefano Zampini const PetscInt *gidxs; 8274f2d7cafSStefano Zampini PetscInt nleaves; 82828f4e0baSStefano Zampini PetscErrorCode ierr; 82928f4e0baSStefano Zampini 83028f4e0baSStefano Zampini PetscFunctionBegin; 8314f2d7cafSStefano Zampini if (matis->sf) PetscFunctionReturn(0); 83228f4e0baSStefano Zampini ierr = PetscSFCreate(PetscObjectComm((PetscObject)B),&matis->sf);CHKERRQ(ierr); 8333bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(B->rmap->mapping,&gidxs);CHKERRQ(ierr); 8344f2d7cafSStefano Zampini ierr = ISLocalToGlobalMappingGetSize(B->rmap->mapping,&nleaves);CHKERRQ(ierr); 8354f2d7cafSStefano Zampini ierr = PetscSFSetGraphLayout(matis->sf,B->rmap,nleaves,NULL,PETSC_OWN_POINTER,gidxs);CHKERRQ(ierr); 8363bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(B->rmap->mapping,&gidxs);CHKERRQ(ierr); 8374f2d7cafSStefano Zampini ierr = PetscMalloc2(matis->sf->nroots,&matis->sf_rootdata,matis->sf->nleaves,&matis->sf_leafdata);CHKERRQ(ierr); 838a8116848SStefano Zampini if (B->rmap->mapping != B->cmap->mapping) { /* setup SF for columns */ 8393d996552SStefano Zampini ierr = ISLocalToGlobalMappingGetSize(B->cmap->mapping,&nleaves);CHKERRQ(ierr); 840a8116848SStefano Zampini ierr = PetscSFCreate(PetscObjectComm((PetscObject)B),&matis->csf);CHKERRQ(ierr); 841a8116848SStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(B->cmap->mapping,&gidxs);CHKERRQ(ierr); 8423d996552SStefano Zampini ierr = PetscSFSetGraphLayout(matis->csf,B->cmap,nleaves,NULL,PETSC_OWN_POINTER,gidxs);CHKERRQ(ierr); 843a8116848SStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(B->cmap->mapping,&gidxs);CHKERRQ(ierr); 8443d996552SStefano Zampini ierr = PetscMalloc2(matis->csf->nroots,&matis->csf_rootdata,matis->csf->nleaves,&matis->csf_leafdata);CHKERRQ(ierr); 845a8116848SStefano Zampini } else { 846a8116848SStefano Zampini matis->csf = matis->sf; 847a8116848SStefano Zampini matis->csf_leafdata = matis->sf_leafdata; 848a8116848SStefano Zampini matis->csf_rootdata = matis->sf_rootdata; 849a8116848SStefano Zampini } 85028f4e0baSStefano Zampini PetscFunctionReturn(0); 85128f4e0baSStefano Zampini } 8522e1947a5SStefano Zampini 8532e1947a5SStefano Zampini #undef __FUNCT__ 8542e1947a5SStefano Zampini #define __FUNCT__ "MatISSetPreallocation" 855eb82efa4SStefano Zampini /*@ 856a88811baSStefano Zampini MatISSetPreallocation - Preallocates memory for a MATIS parallel matrix. 857a88811baSStefano Zampini 858a88811baSStefano Zampini Collective on MPI_Comm 859a88811baSStefano Zampini 860a88811baSStefano Zampini Input Parameters: 861a88811baSStefano Zampini + B - the matrix 862a88811baSStefano Zampini . d_nz - number of nonzeros per row in DIAGONAL portion of local submatrix 863a88811baSStefano Zampini (same value is used for all local rows) 864a88811baSStefano Zampini . d_nnz - array containing the number of nonzeros in the various rows of the 865a88811baSStefano Zampini DIAGONAL portion of the local submatrix (possibly different for each row) 866a88811baSStefano Zampini or NULL, if d_nz is used to specify the nonzero structure. 867a88811baSStefano Zampini The size of this array is equal to the number of local rows, i.e 'm'. 868a88811baSStefano Zampini For matrices that will be factored, you must leave room for (and set) 869a88811baSStefano Zampini the diagonal entry even if it is zero. 870a88811baSStefano Zampini . o_nz - number of nonzeros per row in the OFF-DIAGONAL portion of local 871a88811baSStefano Zampini submatrix (same value is used for all local rows). 872a88811baSStefano Zampini - o_nnz - array containing the number of nonzeros in the various rows of the 873a88811baSStefano Zampini OFF-DIAGONAL portion of the local submatrix (possibly different for 874a88811baSStefano Zampini each row) or NULL, if o_nz is used to specify the nonzero 875a88811baSStefano Zampini structure. The size of this array is equal to the number 876a88811baSStefano Zampini of local rows, i.e 'm'. 877a88811baSStefano Zampini 878a88811baSStefano Zampini If the *_nnz parameter is given then the *_nz parameter is ignored 879a88811baSStefano Zampini 880a88811baSStefano Zampini Level: intermediate 881a88811baSStefano Zampini 882a88811baSStefano Zampini Notes: This function has the same interface as the MPIAIJ preallocation routine in order to simplify the transition 883a88811baSStefano Zampini from the asssembled format to the unassembled one. It overestimates the preallocation of MATIS local 884a88811baSStefano Zampini matrices; for exact preallocation, the user should set the preallocation directly on local matrix objects. 885a88811baSStefano Zampini 886a88811baSStefano Zampini .keywords: matrix 887a88811baSStefano Zampini 8883c212e90SHong Zhang .seealso: MatCreate(), MatCreateIS(), MatMPIAIJSetPreallocation(), MatISGetLocalMat(), MATIS 889a88811baSStefano Zampini @*/ 8902e1947a5SStefano Zampini PetscErrorCode MatISSetPreallocation(Mat B,PetscInt d_nz,const PetscInt d_nnz[],PetscInt o_nz,const PetscInt o_nnz[]) 8912e1947a5SStefano Zampini { 8922e1947a5SStefano Zampini PetscErrorCode ierr; 8932e1947a5SStefano Zampini 8942e1947a5SStefano Zampini PetscFunctionBegin; 8952e1947a5SStefano Zampini PetscValidHeaderSpecific(B,MAT_CLASSID,1); 8962e1947a5SStefano Zampini PetscValidType(B,1); 8972e1947a5SStefano Zampini ierr = PetscTryMethod(B,"MatISSetPreallocation_C",(Mat,PetscInt,const PetscInt[],PetscInt,const PetscInt[]),(B,d_nz,d_nnz,o_nz,o_nnz));CHKERRQ(ierr); 8982e1947a5SStefano Zampini PetscFunctionReturn(0); 8992e1947a5SStefano Zampini } 9002e1947a5SStefano Zampini 9012e1947a5SStefano Zampini #undef __FUNCT__ 9022e1947a5SStefano Zampini #define __FUNCT__ "MatISSetPreallocation_IS" 9037230de76SStefano Zampini static PetscErrorCode MatISSetPreallocation_IS(Mat B,PetscInt d_nz,const PetscInt d_nnz[],PetscInt o_nz,const PetscInt o_nnz[]) 9042e1947a5SStefano Zampini { 9052e1947a5SStefano Zampini Mat_IS *matis = (Mat_IS*)(B->data); 90628f4e0baSStefano Zampini PetscInt bs,i,nlocalcols; 9072e1947a5SStefano Zampini PetscErrorCode ierr; 9082e1947a5SStefano Zampini 9092e1947a5SStefano Zampini PetscFunctionBegin; 9106c4ed002SBarry Smith if (!matis->A) SETERRQ(PetscObjectComm((PetscObject)B),PETSC_ERR_SUP,"You should first call MatSetLocalToGlobalMapping"); 911cf0a3239SStefano Zampini ierr = MatISSetUpSF(B);CHKERRQ(ierr); 9124f2d7cafSStefano Zampini 9134f2d7cafSStefano Zampini if (!d_nnz) for (i=0;i<matis->sf->nroots;i++) matis->sf_rootdata[i] = d_nz; 9144f2d7cafSStefano Zampini else for (i=0;i<matis->sf->nroots;i++) matis->sf_rootdata[i] = d_nnz[i]; 9154f2d7cafSStefano Zampini 9164f2d7cafSStefano Zampini if (!o_nnz) for (i=0;i<matis->sf->nroots;i++) matis->sf_rootdata[i] += o_nz; 9174f2d7cafSStefano Zampini else for (i=0;i<matis->sf->nroots;i++) matis->sf_rootdata[i] += o_nnz[i]; 9184f2d7cafSStefano Zampini 91928f4e0baSStefano Zampini ierr = PetscSFBcastBegin(matis->sf,MPIU_INT,matis->sf_rootdata,matis->sf_leafdata);CHKERRQ(ierr); 92028f4e0baSStefano Zampini ierr = MatGetSize(matis->A,NULL,&nlocalcols);CHKERRQ(ierr); 92128f4e0baSStefano Zampini ierr = MatGetBlockSize(matis->A,&bs);CHKERRQ(ierr); 92228f4e0baSStefano Zampini ierr = PetscSFBcastEnd(matis->sf,MPIU_INT,matis->sf_rootdata,matis->sf_leafdata);CHKERRQ(ierr); 9234f2d7cafSStefano Zampini 9244f2d7cafSStefano Zampini for (i=0;i<matis->sf->nleaves;i++) matis->sf_leafdata[i] = PetscMin(matis->sf_leafdata[i],nlocalcols); 92528f4e0baSStefano Zampini ierr = MatSeqAIJSetPreallocation(matis->A,0,matis->sf_leafdata);CHKERRQ(ierr); 9264f2d7cafSStefano Zampini 9274f2d7cafSStefano Zampini for (i=0;i<matis->sf->nleaves/bs;i++) matis->sf_leafdata[i] = matis->sf_leafdata[i*bs]/bs; 92828f4e0baSStefano Zampini ierr = MatSeqBAIJSetPreallocation(matis->A,bs,0,matis->sf_leafdata);CHKERRQ(ierr); 9294f2d7cafSStefano Zampini 9304f2d7cafSStefano Zampini for (i=0;i<matis->sf->nleaves/bs;i++) matis->sf_leafdata[i] = matis->sf_leafdata[i]-i; 93128f4e0baSStefano Zampini ierr = MatSeqSBAIJSetPreallocation(matis->A,bs,0,matis->sf_leafdata);CHKERRQ(ierr); 9322e1947a5SStefano Zampini PetscFunctionReturn(0); 9332e1947a5SStefano Zampini } 934b4319ba4SBarry Smith 935b4319ba4SBarry Smith #undef __FUNCT__ 9363927de2eSStefano Zampini #define __FUNCT__ "MatISSetMPIXAIJPreallocation_Private" 9373927de2eSStefano Zampini PETSC_EXTERN PetscErrorCode MatISSetMPIXAIJPreallocation_Private(Mat A, Mat B, PetscBool maxreduce) 9383927de2eSStefano Zampini { 9393927de2eSStefano Zampini Mat_IS *matis = (Mat_IS*)(A->data); 9403927de2eSStefano Zampini PetscInt *my_dnz,*my_onz,*dnz,*onz,*mat_ranges,*row_ownership; 941ecf5a873SStefano Zampini const PetscInt *global_indices_r,*global_indices_c; 9423927de2eSStefano Zampini PetscInt i,j,bs,rows,cols; 9433927de2eSStefano Zampini PetscInt lrows,lcols; 9443927de2eSStefano Zampini PetscInt local_rows,local_cols; 9453927de2eSStefano Zampini PetscMPIInt nsubdomains; 9463927de2eSStefano Zampini PetscBool isdense,issbaij; 9473927de2eSStefano Zampini PetscErrorCode ierr; 9483927de2eSStefano Zampini 9493927de2eSStefano Zampini PetscFunctionBegin; 9503927de2eSStefano Zampini ierr = MPI_Comm_size(PetscObjectComm((PetscObject)A),&nsubdomains);CHKERRQ(ierr); 9513927de2eSStefano Zampini ierr = MatGetSize(A,&rows,&cols);CHKERRQ(ierr); 9523927de2eSStefano Zampini ierr = MatGetBlockSize(A,&bs);CHKERRQ(ierr); 9533927de2eSStefano Zampini ierr = MatGetSize(matis->A,&local_rows,&local_cols);CHKERRQ(ierr); 9543927de2eSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)matis->A,MATSEQDENSE,&isdense);CHKERRQ(ierr); 9553927de2eSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)matis->A,MATSEQSBAIJ,&issbaij);CHKERRQ(ierr); 956ecf5a873SStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(A->rmap->mapping,&global_indices_r);CHKERRQ(ierr); 957ecf5a873SStefano Zampini if (A->rmap->mapping != A->cmap->mapping) { 9587230de76SStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(A->cmap->mapping,&global_indices_c);CHKERRQ(ierr); 959ecf5a873SStefano Zampini } else { 960ecf5a873SStefano Zampini global_indices_c = global_indices_r; 961ecf5a873SStefano Zampini } 962ecf5a873SStefano Zampini 9633927de2eSStefano Zampini if (issbaij) { 9643927de2eSStefano Zampini ierr = MatGetRowUpperTriangular(matis->A);CHKERRQ(ierr); 9653927de2eSStefano Zampini } 9663927de2eSStefano Zampini /* 967ecf5a873SStefano Zampini An SF reduce is needed to sum up properly on shared rows. 9683927de2eSStefano Zampini Note that generally preallocation is not exact, since it overestimates nonzeros 9693927de2eSStefano Zampini */ 970cf0a3239SStefano Zampini ierr = MatISSetUpSF(A);CHKERRQ(ierr); 9713927de2eSStefano Zampini ierr = MatGetLocalSize(A,&lrows,&lcols);CHKERRQ(ierr); 9723927de2eSStefano Zampini ierr = MatPreallocateInitialize(PetscObjectComm((PetscObject)A),lrows,lcols,dnz,onz);CHKERRQ(ierr); 9733927de2eSStefano Zampini /* All processes need to compute entire row ownership */ 9743927de2eSStefano Zampini ierr = PetscMalloc1(rows,&row_ownership);CHKERRQ(ierr); 9753927de2eSStefano Zampini ierr = MatGetOwnershipRanges(A,(const PetscInt**)&mat_ranges);CHKERRQ(ierr); 9763927de2eSStefano Zampini for (i=0;i<nsubdomains;i++) { 9773927de2eSStefano Zampini for (j=mat_ranges[i];j<mat_ranges[i+1];j++) { 9783927de2eSStefano Zampini row_ownership[j] = i; 9793927de2eSStefano Zampini } 9803927de2eSStefano Zampini } 9817230de76SStefano Zampini ierr = MatGetOwnershipRangesColumn(A,(const PetscInt**)&mat_ranges);CHKERRQ(ierr); 9823927de2eSStefano Zampini 9833927de2eSStefano Zampini /* 9843927de2eSStefano Zampini my_dnz and my_onz contains exact contribution to preallocation from each local mat 9853927de2eSStefano Zampini then, they will be summed up properly. This way, preallocation is always sufficient 9863927de2eSStefano Zampini */ 9873927de2eSStefano Zampini ierr = PetscCalloc2(local_rows,&my_dnz,local_rows,&my_onz);CHKERRQ(ierr); 9883927de2eSStefano Zampini /* preallocation as a MATAIJ */ 9893927de2eSStefano Zampini if (isdense) { /* special case for dense local matrices */ 9903927de2eSStefano Zampini for (i=0;i<local_rows;i++) { 991ecf5a873SStefano Zampini PetscInt index_row = global_indices_r[i]; 9923927de2eSStefano Zampini for (j=i;j<local_rows;j++) { 9933927de2eSStefano Zampini PetscInt owner = row_ownership[index_row]; 994ecf5a873SStefano Zampini PetscInt index_col = global_indices_c[j]; 9953927de2eSStefano Zampini if (index_col > mat_ranges[owner]-1 && index_col < mat_ranges[owner+1] ) { /* diag block */ 9963927de2eSStefano Zampini my_dnz[i] += 1; 9973927de2eSStefano Zampini } else { /* offdiag block */ 9983927de2eSStefano Zampini my_onz[i] += 1; 9993927de2eSStefano Zampini } 10003927de2eSStefano Zampini /* same as before, interchanging rows and cols */ 10013927de2eSStefano Zampini if (i != j) { 10023927de2eSStefano Zampini owner = row_ownership[index_col]; 10033927de2eSStefano Zampini if (index_row > mat_ranges[owner]-1 && index_row < mat_ranges[owner+1] ) { 10043927de2eSStefano Zampini my_dnz[j] += 1; 10053927de2eSStefano Zampini } else { 10063927de2eSStefano Zampini my_onz[j] += 1; 10073927de2eSStefano Zampini } 10083927de2eSStefano Zampini } 10093927de2eSStefano Zampini } 10103927de2eSStefano Zampini } 1011bb1015c3SStefano Zampini } else if (matis->A->ops->getrowij) { 1012bb1015c3SStefano Zampini const PetscInt *ii,*jj,*jptr; 1013bb1015c3SStefano Zampini PetscBool done; 1014bb1015c3SStefano Zampini ierr = MatGetRowIJ(matis->A,0,PETSC_FALSE,PETSC_FALSE,&local_rows,&ii,&jj,&done);CHKERRQ(ierr); 1015bb1015c3SStefano Zampini if (!done) SETERRQ1(PetscObjectComm((PetscObject)(matis->A)),PETSC_ERR_PLIB,"Error in MatGetRowIJ called from %s\n",__FUNCT__); 1016bb1015c3SStefano Zampini jptr = jj; 1017bb1015c3SStefano Zampini for (i=0;i<local_rows;i++) { 1018bb1015c3SStefano Zampini PetscInt index_row = global_indices_r[i]; 1019bb1015c3SStefano Zampini for (j=0;j<ii[i+1]-ii[i];j++,jptr++) { 1020bb1015c3SStefano Zampini PetscInt owner = row_ownership[index_row]; 1021bb1015c3SStefano Zampini PetscInt index_col = global_indices_c[*jptr]; 1022bb1015c3SStefano Zampini if (index_col > mat_ranges[owner]-1 && index_col < mat_ranges[owner+1] ) { /* diag block */ 1023bb1015c3SStefano Zampini my_dnz[i] += 1; 1024bb1015c3SStefano Zampini } else { /* offdiag block */ 1025bb1015c3SStefano Zampini my_onz[i] += 1; 1026bb1015c3SStefano Zampini } 1027bb1015c3SStefano Zampini /* same as before, interchanging rows and cols */ 1028bb1015c3SStefano Zampini if (issbaij && index_col != index_row) { 1029bb1015c3SStefano Zampini owner = row_ownership[index_col]; 1030bb1015c3SStefano Zampini if (index_row > mat_ranges[owner]-1 && index_row < mat_ranges[owner+1] ) { 1031bb1015c3SStefano Zampini my_dnz[*jptr] += 1; 1032bb1015c3SStefano Zampini } else { 1033bb1015c3SStefano Zampini my_onz[*jptr] += 1; 1034bb1015c3SStefano Zampini } 1035bb1015c3SStefano Zampini } 1036bb1015c3SStefano Zampini } 1037bb1015c3SStefano Zampini } 1038bb1015c3SStefano Zampini ierr = MatRestoreRowIJ(matis->A,0,PETSC_FALSE,PETSC_FALSE,&local_rows,&ii,&jj,&done);CHKERRQ(ierr); 1039bb1015c3SStefano Zampini if (!done) SETERRQ1(PetscObjectComm((PetscObject)(matis->A)),PETSC_ERR_PLIB,"Error in MatRestoreRowIJ called from %s\n",__FUNCT__); 1040bb1015c3SStefano Zampini } else { /* loop over rows and use MatGetRow */ 10413927de2eSStefano Zampini for (i=0;i<local_rows;i++) { 10423927de2eSStefano Zampini const PetscInt *cols; 1043ecf5a873SStefano Zampini PetscInt ncols,index_row = global_indices_r[i]; 10443927de2eSStefano Zampini ierr = MatGetRow(matis->A,i,&ncols,&cols,NULL);CHKERRQ(ierr); 10453927de2eSStefano Zampini for (j=0;j<ncols;j++) { 10463927de2eSStefano Zampini PetscInt owner = row_ownership[index_row]; 1047ecf5a873SStefano Zampini PetscInt index_col = global_indices_c[cols[j]]; 10483927de2eSStefano Zampini if (index_col > mat_ranges[owner]-1 && index_col < mat_ranges[owner+1] ) { /* diag block */ 10493927de2eSStefano Zampini my_dnz[i] += 1; 10503927de2eSStefano Zampini } else { /* offdiag block */ 10513927de2eSStefano Zampini my_onz[i] += 1; 10523927de2eSStefano Zampini } 10533927de2eSStefano Zampini /* same as before, interchanging rows and cols */ 1054d9a9e74cSStefano Zampini if (issbaij && index_col != index_row) { 10553927de2eSStefano Zampini owner = row_ownership[index_col]; 10563927de2eSStefano Zampini if (index_row > mat_ranges[owner]-1 && index_row < mat_ranges[owner+1] ) { 1057d9a9e74cSStefano Zampini my_dnz[cols[j]] += 1; 10583927de2eSStefano Zampini } else { 1059d9a9e74cSStefano Zampini my_onz[cols[j]] += 1; 10603927de2eSStefano Zampini } 10613927de2eSStefano Zampini } 10623927de2eSStefano Zampini } 10633927de2eSStefano Zampini ierr = MatRestoreRow(matis->A,i,&ncols,&cols,NULL);CHKERRQ(ierr); 10643927de2eSStefano Zampini } 10653927de2eSStefano Zampini } 1066ecf5a873SStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(A->rmap->mapping,&global_indices_r);CHKERRQ(ierr); 1067ecf5a873SStefano Zampini if (global_indices_c != global_indices_r) { 10687230de76SStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(A->cmap->mapping,&global_indices_c);CHKERRQ(ierr); 1069ecf5a873SStefano Zampini } 10703927de2eSStefano Zampini ierr = PetscFree(row_ownership);CHKERRQ(ierr); 1071ecf5a873SStefano Zampini 1072ecf5a873SStefano Zampini /* Reduce my_dnz and my_onz */ 10733927de2eSStefano Zampini if (maxreduce) { 10743927de2eSStefano Zampini ierr = PetscSFReduceBegin(matis->sf,MPIU_INT,my_dnz,dnz,MPI_MAX);CHKERRQ(ierr); 10753927de2eSStefano Zampini ierr = PetscSFReduceBegin(matis->sf,MPIU_INT,my_onz,onz,MPI_MAX);CHKERRQ(ierr); 1076bb1015c3SStefano Zampini ierr = PetscSFReduceEnd(matis->sf,MPIU_INT,my_dnz,dnz,MPI_MAX);CHKERRQ(ierr); 10773927de2eSStefano Zampini ierr = PetscSFReduceEnd(matis->sf,MPIU_INT,my_onz,onz,MPI_MAX);CHKERRQ(ierr); 10783927de2eSStefano Zampini } else { 10793927de2eSStefano Zampini ierr = PetscSFReduceBegin(matis->sf,MPIU_INT,my_dnz,dnz,MPI_SUM);CHKERRQ(ierr); 10803927de2eSStefano Zampini ierr = PetscSFReduceBegin(matis->sf,MPIU_INT,my_onz,onz,MPI_SUM);CHKERRQ(ierr); 1081bb1015c3SStefano Zampini ierr = PetscSFReduceEnd(matis->sf,MPIU_INT,my_dnz,dnz,MPI_SUM);CHKERRQ(ierr); 10823927de2eSStefano Zampini ierr = PetscSFReduceEnd(matis->sf,MPIU_INT,my_onz,onz,MPI_SUM);CHKERRQ(ierr); 10833927de2eSStefano Zampini } 10843927de2eSStefano Zampini ierr = PetscFree2(my_dnz,my_onz);CHKERRQ(ierr); 10853927de2eSStefano Zampini 10863927de2eSStefano Zampini /* Resize preallocation if overestimated */ 10873927de2eSStefano Zampini for (i=0;i<lrows;i++) { 10883927de2eSStefano Zampini dnz[i] = PetscMin(dnz[i],lcols); 10893927de2eSStefano Zampini onz[i] = PetscMin(onz[i],cols-lcols); 10903927de2eSStefano Zampini } 10911670daf9Sstefano_zampini 10921670daf9Sstefano_zampini /* Set preallocation */ 10933927de2eSStefano Zampini ierr = MatMPIAIJSetPreallocation(B,0,dnz,0,onz);CHKERRQ(ierr); 10943927de2eSStefano Zampini for (i=0;i<lrows/bs;i++) { 10953927de2eSStefano Zampini dnz[i] = dnz[i*bs]/bs; 10963927de2eSStefano Zampini onz[i] = onz[i*bs]/bs; 10973927de2eSStefano Zampini } 10983927de2eSStefano Zampini ierr = MatMPIBAIJSetPreallocation(B,bs,0,dnz,0,onz);CHKERRQ(ierr); 10993927de2eSStefano Zampini ierr = MatMPISBAIJSetPreallocation(B,bs,0,dnz,0,onz);CHKERRQ(ierr); 11003927de2eSStefano Zampini ierr = MatPreallocateFinalize(dnz,onz);CHKERRQ(ierr); 11013927de2eSStefano Zampini if (issbaij) { 11023927de2eSStefano Zampini ierr = MatRestoreRowUpperTriangular(matis->A);CHKERRQ(ierr); 11033927de2eSStefano Zampini } 11043927de2eSStefano Zampini PetscFunctionReturn(0); 11053927de2eSStefano Zampini } 11063927de2eSStefano Zampini 11073927de2eSStefano Zampini #undef __FUNCT__ 1108b7ce53b6SStefano Zampini #define __FUNCT__ "MatISGetMPIXAIJ_IS" 11097230de76SStefano Zampini static PetscErrorCode MatISGetMPIXAIJ_IS(Mat mat, MatReuse reuse, Mat *M) 1110b7ce53b6SStefano Zampini { 1111b7ce53b6SStefano Zampini Mat_IS *matis = (Mat_IS*)(mat->data); 1112d9a9e74cSStefano Zampini Mat local_mat; 1113b7ce53b6SStefano Zampini /* info on mat */ 11143cfa4ea4SStefano Zampini PetscInt bs,rows,cols,lrows,lcols; 1115b7ce53b6SStefano Zampini PetscInt local_rows,local_cols; 1116b9ed4604SStefano Zampini PetscBool isseqdense,isseqsbaij,isseqaij,isseqbaij; 1117b9ed4604SStefano Zampini #if defined (PETSC_USE_DEBUG) 1118b9ed4604SStefano Zampini PetscBool lb[4],bb[4]; 1119b9ed4604SStefano Zampini #endif 11207c03b4e8SStefano Zampini PetscMPIInt nsubdomains; 1121b7ce53b6SStefano Zampini /* values insertion */ 1122b7ce53b6SStefano Zampini PetscScalar *array; 1123b7ce53b6SStefano Zampini /* work */ 1124b7ce53b6SStefano Zampini PetscErrorCode ierr; 1125b7ce53b6SStefano Zampini 1126b7ce53b6SStefano Zampini PetscFunctionBegin; 1127b7ce53b6SStefano Zampini /* get info from mat */ 11287c03b4e8SStefano Zampini ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&nsubdomains);CHKERRQ(ierr); 11297c03b4e8SStefano Zampini if (nsubdomains == 1) { 11301670daf9Sstefano_zampini Mat B; 11311670daf9Sstefano_zampini IS rows,cols; 1132*acdf38a7Sstefano_zampini IS irows,icols; 11331670daf9Sstefano_zampini const PetscInt *ridxs,*cidxs; 11341670daf9Sstefano_zampini 11351670daf9Sstefano_zampini ierr = ISLocalToGlobalMappingGetIndices(mat->rmap->mapping,&ridxs);CHKERRQ(ierr); 11361670daf9Sstefano_zampini ierr = ISLocalToGlobalMappingGetIndices(mat->cmap->mapping,&cidxs);CHKERRQ(ierr); 11371670daf9Sstefano_zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,mat->rmap->n,ridxs,PETSC_USE_POINTER,&rows);CHKERRQ(ierr); 11381670daf9Sstefano_zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,mat->cmap->n,cidxs,PETSC_USE_POINTER,&cols);CHKERRQ(ierr); 11391670daf9Sstefano_zampini ierr = ISLocalToGlobalMappingRestoreIndices(mat->rmap->mapping,&ridxs);CHKERRQ(ierr); 11401670daf9Sstefano_zampini ierr = ISLocalToGlobalMappingRestoreIndices(mat->cmap->mapping,&cidxs);CHKERRQ(ierr); 1141*acdf38a7Sstefano_zampini ierr = ISSetPermutation(rows);CHKERRQ(ierr); 1142*acdf38a7Sstefano_zampini ierr = ISSetPermutation(cols);CHKERRQ(ierr); 1143*acdf38a7Sstefano_zampini ierr = ISInvertPermutation(rows,mat->rmap->n,&irows);CHKERRQ(ierr); 1144*acdf38a7Sstefano_zampini ierr = ISInvertPermutation(cols,mat->cmap->n,&icols);CHKERRQ(ierr); 1145*acdf38a7Sstefano_zampini ierr = ISDestroy(&cols);CHKERRQ(ierr); 1146*acdf38a7Sstefano_zampini ierr = ISDestroy(&rows);CHKERRQ(ierr); 1147*acdf38a7Sstefano_zampini ierr = MatConvert(matis->A,MATAIJ,MAT_INITIAL_MATRIX,&B);CHKERRQ(ierr); 1148*acdf38a7Sstefano_zampini ierr = MatGetSubMatrix(B,irows,icols,reuse,M);CHKERRQ(ierr); 1149*acdf38a7Sstefano_zampini ierr = MatDestroy(&B);CHKERRQ(ierr); 1150*acdf38a7Sstefano_zampini ierr = ISDestroy(&icols);CHKERRQ(ierr); 1151*acdf38a7Sstefano_zampini ierr = ISDestroy(&irows);CHKERRQ(ierr); 11527c03b4e8SStefano Zampini PetscFunctionReturn(0); 11537c03b4e8SStefano Zampini } 1154b7ce53b6SStefano Zampini ierr = MatGetSize(mat,&rows,&cols);CHKERRQ(ierr); 1155b7ce53b6SStefano Zampini ierr = MatGetBlockSize(mat,&bs);CHKERRQ(ierr); 11563cfa4ea4SStefano Zampini ierr = MatGetLocalSize(mat,&lrows,&lcols);CHKERRQ(ierr); 1157b7ce53b6SStefano Zampini ierr = MatGetSize(matis->A,&local_rows,&local_cols);CHKERRQ(ierr); 1158b9ed4604SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)matis->A,MATSEQDENSE,&isseqdense);CHKERRQ(ierr); 1159686e3a49SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)matis->A,MATSEQAIJ,&isseqaij);CHKERRQ(ierr); 1160b9ed4604SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)matis->A,MATSEQBAIJ,&isseqbaij);CHKERRQ(ierr); 1161b9ed4604SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)matis->A,MATSEQSBAIJ,&isseqsbaij);CHKERRQ(ierr); 1162b9ed4604SStefano Zampini if (!isseqdense && !isseqaij && !isseqbaij && !isseqsbaij) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not for matrix type %s",((PetscObject)(matis->A))->type_name); 1163b9ed4604SStefano Zampini #if defined (PETSC_USE_DEBUG) 1164b9ed4604SStefano Zampini lb[0] = isseqdense; 1165b9ed4604SStefano Zampini lb[1] = isseqaij; 1166b9ed4604SStefano Zampini lb[2] = isseqbaij; 1167b9ed4604SStefano Zampini lb[3] = isseqsbaij; 1168b9ed4604SStefano Zampini ierr = MPIU_Allreduce(lb,bb,4,MPIU_BOOL,MPI_LAND,PetscObjectComm((PetscObject)mat));CHKERRQ(ierr); 1169b9ed4604SStefano Zampini if (!bb[0] && !bb[1] && !bb[2] && !bb[3]) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Local matrices must have the same type"); 1170b9ed4604SStefano Zampini #endif 1171b7ce53b6SStefano Zampini 1172b7ce53b6SStefano Zampini if (reuse == MAT_INITIAL_MATRIX) { 11733927de2eSStefano Zampini ierr = MatCreate(PetscObjectComm((PetscObject)mat),M);CHKERRQ(ierr); 11743cfa4ea4SStefano Zampini ierr = MatSetSizes(*M,lrows,lcols,rows,cols);CHKERRQ(ierr); 11753927de2eSStefano Zampini ierr = MatSetBlockSize(*M,bs);CHKERRQ(ierr); 1176b9ed4604SStefano Zampini if (!isseqsbaij) { 1177b9ed4604SStefano Zampini ierr = MatSetType(*M,MATAIJ);CHKERRQ(ierr); 1178b9ed4604SStefano Zampini } else { 1179b9ed4604SStefano Zampini ierr = MatSetType(*M,MATSBAIJ);CHKERRQ(ierr); 1180b9ed4604SStefano Zampini } 11813927de2eSStefano Zampini ierr = MatISSetMPIXAIJPreallocation_Private(mat,*M,PETSC_FALSE);CHKERRQ(ierr); 1182b7ce53b6SStefano Zampini } else { 11833cfa4ea4SStefano Zampini PetscInt mbs,mrows,mcols,mlrows,mlcols; 1184b7ce53b6SStefano Zampini /* some checks */ 1185b7ce53b6SStefano Zampini ierr = MatGetBlockSize(*M,&mbs);CHKERRQ(ierr); 1186b7ce53b6SStefano Zampini ierr = MatGetSize(*M,&mrows,&mcols);CHKERRQ(ierr); 11873cfa4ea4SStefano Zampini ierr = MatGetLocalSize(*M,&mlrows,&mlcols);CHKERRQ(ierr); 11886c4ed002SBarry Smith if (mrows != rows) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot reuse matrix. Wrong number of rows (%d != %d)",rows,mrows); 11896c4ed002SBarry Smith if (mcols != cols) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot reuse matrix. Wrong number of cols (%d != %d)",cols,mcols); 11906c4ed002SBarry Smith if (mlrows != lrows) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot reuse matrix. Wrong number of local rows (%d != %d)",lrows,mlrows); 11916c4ed002SBarry Smith if (mlcols != lcols) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot reuse matrix. Wrong number of local cols (%d != %d)",lcols,mlcols); 11926c4ed002SBarry Smith if (mbs != bs) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot reuse matrix. Wrong block size (%d != %d)",bs,mbs); 1193b7ce53b6SStefano Zampini ierr = MatZeroEntries(*M);CHKERRQ(ierr); 1194b7ce53b6SStefano Zampini } 1195d9a9e74cSStefano Zampini 1196b9ed4604SStefano Zampini if (isseqsbaij) { 1197d9a9e74cSStefano Zampini ierr = MatConvert(matis->A,MATSEQBAIJ,MAT_INITIAL_MATRIX,&local_mat);CHKERRQ(ierr); 1198d9a9e74cSStefano Zampini } else { 1199d9a9e74cSStefano Zampini ierr = PetscObjectReference((PetscObject)matis->A);CHKERRQ(ierr); 1200d9a9e74cSStefano Zampini local_mat = matis->A; 1201d9a9e74cSStefano Zampini } 1202686e3a49SStefano Zampini 1203b7ce53b6SStefano Zampini /* Set values */ 1204ecf5a873SStefano Zampini ierr = MatSetLocalToGlobalMapping(*M,mat->rmap->mapping,mat->cmap->mapping);CHKERRQ(ierr); 1205b9ed4604SStefano Zampini if (isseqdense) { /* special case for dense local matrices */ 1206ecf5a873SStefano Zampini PetscInt i,*dummy_rows,*dummy_cols; 1207ecf5a873SStefano Zampini 1208ecf5a873SStefano Zampini if (local_rows != local_cols) { 1209ecf5a873SStefano Zampini ierr = PetscMalloc2(local_rows,&dummy_rows,local_cols,&dummy_cols);CHKERRQ(ierr); 1210ecf5a873SStefano Zampini for (i=0;i<local_rows;i++) dummy_rows[i] = i; 1211ecf5a873SStefano Zampini for (i=0;i<local_cols;i++) dummy_cols[i] = i; 1212ecf5a873SStefano Zampini } else { 1213ecf5a873SStefano Zampini ierr = PetscMalloc1(local_rows,&dummy_rows);CHKERRQ(ierr); 1214ecf5a873SStefano Zampini for (i=0;i<local_rows;i++) dummy_rows[i] = i; 1215ecf5a873SStefano Zampini dummy_cols = dummy_rows; 1216ecf5a873SStefano Zampini } 1217b7ce53b6SStefano Zampini ierr = MatSetOption(*M,MAT_ROW_ORIENTED,PETSC_FALSE);CHKERRQ(ierr); 1218d9a9e74cSStefano Zampini ierr = MatDenseGetArray(local_mat,&array);CHKERRQ(ierr); 1219ecf5a873SStefano Zampini ierr = MatSetValuesLocal(*M,local_rows,dummy_rows,local_cols,dummy_cols,array,ADD_VALUES);CHKERRQ(ierr); 1220d9a9e74cSStefano Zampini ierr = MatDenseRestoreArray(local_mat,&array);CHKERRQ(ierr); 1221ecf5a873SStefano Zampini if (dummy_rows != dummy_cols) { 1222ecf5a873SStefano Zampini ierr = PetscFree2(dummy_rows,dummy_cols);CHKERRQ(ierr); 1223ecf5a873SStefano Zampini } else { 1224ecf5a873SStefano Zampini ierr = PetscFree(dummy_rows);CHKERRQ(ierr); 1225ecf5a873SStefano Zampini } 1226686e3a49SStefano Zampini } else if (isseqaij) { 1227ecf5a873SStefano Zampini PetscInt i,nvtxs,*xadj,*adjncy; 1228686e3a49SStefano Zampini PetscBool done; 1229686e3a49SStefano Zampini 1230d9a9e74cSStefano Zampini ierr = MatGetRowIJ(local_mat,0,PETSC_FALSE,PETSC_FALSE,&nvtxs,(const PetscInt**)&xadj,(const PetscInt**)&adjncy,&done);CHKERRQ(ierr); 1231bb1015c3SStefano Zampini if (!done) SETERRQ1(PetscObjectComm((PetscObject)local_mat),PETSC_ERR_PLIB,"Error in MatGetRowIJ called from %s\n",__FUNCT__); 1232d9a9e74cSStefano Zampini ierr = MatSeqAIJGetArray(local_mat,&array);CHKERRQ(ierr); 1233686e3a49SStefano Zampini for (i=0;i<nvtxs;i++) { 1234ecf5a873SStefano Zampini ierr = MatSetValuesLocal(*M,1,&i,xadj[i+1]-xadj[i],adjncy+xadj[i],array+xadj[i],ADD_VALUES);CHKERRQ(ierr); 1235686e3a49SStefano Zampini } 1236d9a9e74cSStefano Zampini ierr = MatRestoreRowIJ(local_mat,0,PETSC_FALSE,PETSC_FALSE,&nvtxs,(const PetscInt**)&xadj,(const PetscInt**)&adjncy,&done);CHKERRQ(ierr); 1237bb1015c3SStefano Zampini if (!done) SETERRQ1(PetscObjectComm((PetscObject)local_mat),PETSC_ERR_PLIB,"Error in MatRestoreRowIJ called from %s\n",__FUNCT__); 1238d9a9e74cSStefano Zampini ierr = MatSeqAIJRestoreArray(local_mat,&array);CHKERRQ(ierr); 1239686e3a49SStefano Zampini } else { /* very basic values insertion for all other matrix types */ 1240ecf5a873SStefano Zampini PetscInt i; 1241c0962df8SStefano Zampini 1242686e3a49SStefano Zampini for (i=0;i<local_rows;i++) { 1243686e3a49SStefano Zampini PetscInt j; 1244ecf5a873SStefano Zampini const PetscInt *local_indices_cols; 1245686e3a49SStefano Zampini 1246ecf5a873SStefano Zampini ierr = MatGetRow(local_mat,i,&j,&local_indices_cols,(const PetscScalar**)&array);CHKERRQ(ierr); 1247ecf5a873SStefano Zampini ierr = MatSetValuesLocal(*M,1,&i,j,local_indices_cols,array,ADD_VALUES);CHKERRQ(ierr); 1248ecf5a873SStefano Zampini ierr = MatRestoreRow(local_mat,i,&j,&local_indices_cols,(const PetscScalar**)&array);CHKERRQ(ierr); 1249686e3a49SStefano Zampini } 1250b7ce53b6SStefano Zampini } 1251b7ce53b6SStefano Zampini ierr = MatAssemblyBegin(*M,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1252d9a9e74cSStefano Zampini ierr = MatDestroy(&local_mat);CHKERRQ(ierr); 1253b7ce53b6SStefano Zampini ierr = MatAssemblyEnd(*M,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1254b9ed4604SStefano Zampini if (isseqdense) { 1255b7ce53b6SStefano Zampini ierr = MatSetOption(*M,MAT_ROW_ORIENTED,PETSC_TRUE);CHKERRQ(ierr); 1256b7ce53b6SStefano Zampini } 1257b7ce53b6SStefano Zampini PetscFunctionReturn(0); 1258b7ce53b6SStefano Zampini } 1259b7ce53b6SStefano Zampini 1260b7ce53b6SStefano Zampini #undef __FUNCT__ 1261b7ce53b6SStefano Zampini #define __FUNCT__ "MatISGetMPIXAIJ" 1262b7ce53b6SStefano Zampini /*@ 1263b7ce53b6SStefano Zampini MatISGetMPIXAIJ - Converts MATIS matrix into a parallel AIJ format 1264b7ce53b6SStefano Zampini 1265b7ce53b6SStefano Zampini Input Parameter: 1266b7ce53b6SStefano Zampini . mat - the matrix (should be of type MATIS) 1267b7ce53b6SStefano Zampini . reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 1268b7ce53b6SStefano Zampini 1269b7ce53b6SStefano Zampini Output Parameter: 1270b7ce53b6SStefano Zampini . newmat - the matrix in AIJ format 1271b7ce53b6SStefano Zampini 1272b7ce53b6SStefano Zampini Level: developer 1273b7ce53b6SStefano Zampini 1274eb82efa4SStefano Zampini Notes: mat and *newmat cannot be the same object when MAT_REUSE_MATRIX is requested. 1275b7ce53b6SStefano Zampini 1276b7ce53b6SStefano Zampini .seealso: MATIS 1277b7ce53b6SStefano Zampini @*/ 1278b7ce53b6SStefano Zampini PetscErrorCode MatISGetMPIXAIJ(Mat mat, MatReuse reuse, Mat *newmat) 1279b7ce53b6SStefano Zampini { 1280b7ce53b6SStefano Zampini PetscErrorCode ierr; 1281b7ce53b6SStefano Zampini 1282b7ce53b6SStefano Zampini PetscFunctionBegin; 1283b7ce53b6SStefano Zampini PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1284b7ce53b6SStefano Zampini PetscValidLogicalCollectiveEnum(mat,reuse,2); 1285b7ce53b6SStefano Zampini PetscValidPointer(newmat,3); 1286b7ce53b6SStefano Zampini if (reuse != MAT_INITIAL_MATRIX) { 1287b7ce53b6SStefano Zampini PetscValidHeaderSpecific(*newmat,MAT_CLASSID,3); 1288b7ce53b6SStefano Zampini PetscCheckSameComm(mat,1,*newmat,3); 12896c4ed002SBarry Smith if (mat == *newmat) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot reuse the same matrix"); 1290b7ce53b6SStefano Zampini } 1291b7ce53b6SStefano Zampini ierr = PetscUseMethod(mat,"MatISGetMPIXAIJ_C",(Mat,MatReuse,Mat*),(mat,reuse,newmat));CHKERRQ(ierr); 1292b7ce53b6SStefano Zampini PetscFunctionReturn(0); 1293b7ce53b6SStefano Zampini } 1294b7ce53b6SStefano Zampini 1295b7ce53b6SStefano Zampini #undef __FUNCT__ 1296ad6194a2SStefano Zampini #define __FUNCT__ "MatDuplicate_IS" 1297ad6194a2SStefano Zampini PetscErrorCode MatDuplicate_IS(Mat mat,MatDuplicateOption op,Mat *newmat) 1298ad6194a2SStefano Zampini { 1299ad6194a2SStefano Zampini PetscErrorCode ierr; 1300ad6194a2SStefano Zampini Mat_IS *matis = (Mat_IS*)(mat->data); 1301ad6194a2SStefano Zampini PetscInt bs,m,n,M,N; 1302ad6194a2SStefano Zampini Mat B,localmat; 1303ad6194a2SStefano Zampini 1304ad6194a2SStefano Zampini PetscFunctionBegin; 1305ad6194a2SStefano Zampini ierr = MatGetBlockSize(mat,&bs);CHKERRQ(ierr); 1306ad6194a2SStefano Zampini ierr = MatGetSize(mat,&M,&N);CHKERRQ(ierr); 1307ad6194a2SStefano Zampini ierr = MatGetLocalSize(mat,&m,&n);CHKERRQ(ierr); 1308e176bc59SStefano Zampini ierr = MatCreateIS(PetscObjectComm((PetscObject)mat),bs,m,n,M,N,mat->rmap->mapping,mat->cmap->mapping,&B);CHKERRQ(ierr); 1309ad6194a2SStefano Zampini ierr = MatDuplicate(matis->A,op,&localmat);CHKERRQ(ierr); 1310ad6194a2SStefano Zampini ierr = MatISSetLocalMat(B,localmat);CHKERRQ(ierr); 1311b3317aa8SStefano Zampini ierr = MatDestroy(&localmat);CHKERRQ(ierr); 1312ad6194a2SStefano Zampini ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1313ad6194a2SStefano Zampini ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1314ad6194a2SStefano Zampini *newmat = B; 1315ad6194a2SStefano Zampini PetscFunctionReturn(0); 1316ad6194a2SStefano Zampini } 1317ad6194a2SStefano Zampini 1318ad6194a2SStefano Zampini #undef __FUNCT__ 131969796d55SStefano Zampini #define __FUNCT__ "MatIsHermitian_IS" 1320a8116848SStefano Zampini static PetscErrorCode MatIsHermitian_IS(Mat A,PetscReal tol,PetscBool *flg) 132169796d55SStefano Zampini { 132269796d55SStefano Zampini PetscErrorCode ierr; 132369796d55SStefano Zampini Mat_IS *matis = (Mat_IS*)A->data; 132469796d55SStefano Zampini PetscBool local_sym; 132569796d55SStefano Zampini 132669796d55SStefano Zampini PetscFunctionBegin; 132769796d55SStefano Zampini ierr = MatIsHermitian(matis->A,tol,&local_sym);CHKERRQ(ierr); 1328b2566f29SBarry Smith ierr = MPIU_Allreduce(&local_sym,flg,1,MPIU_BOOL,MPI_LAND,PetscObjectComm((PetscObject)A));CHKERRQ(ierr); 132969796d55SStefano Zampini PetscFunctionReturn(0); 133069796d55SStefano Zampini } 133169796d55SStefano Zampini 133269796d55SStefano Zampini #undef __FUNCT__ 133369796d55SStefano Zampini #define __FUNCT__ "MatIsSymmetric_IS" 1334a8116848SStefano Zampini static PetscErrorCode MatIsSymmetric_IS(Mat A,PetscReal tol,PetscBool *flg) 133569796d55SStefano Zampini { 133669796d55SStefano Zampini PetscErrorCode ierr; 133769796d55SStefano Zampini Mat_IS *matis = (Mat_IS*)A->data; 133869796d55SStefano Zampini PetscBool local_sym; 133969796d55SStefano Zampini 134069796d55SStefano Zampini PetscFunctionBegin; 134169796d55SStefano Zampini ierr = MatIsSymmetric(matis->A,tol,&local_sym);CHKERRQ(ierr); 1342b2566f29SBarry Smith ierr = MPIU_Allreduce(&local_sym,flg,1,MPIU_BOOL,MPI_LAND,PetscObjectComm((PetscObject)A));CHKERRQ(ierr); 134369796d55SStefano Zampini PetscFunctionReturn(0); 134469796d55SStefano Zampini } 134569796d55SStefano Zampini 134669796d55SStefano Zampini #undef __FUNCT__ 134745471136SStefano Zampini #define __FUNCT__ "MatIsStructurallySymmetric_IS" 134845471136SStefano Zampini static PetscErrorCode MatIsStructurallySymmetric_IS(Mat A,PetscBool *flg) 134945471136SStefano Zampini { 135045471136SStefano Zampini PetscErrorCode ierr; 135145471136SStefano Zampini Mat_IS *matis = (Mat_IS*)A->data; 135245471136SStefano Zampini PetscBool local_sym; 135345471136SStefano Zampini 135445471136SStefano Zampini PetscFunctionBegin; 135545471136SStefano Zampini if (A->rmap->mapping != A->cmap->mapping) { 135645471136SStefano Zampini *flg = PETSC_FALSE; 135745471136SStefano Zampini PetscFunctionReturn(0); 135845471136SStefano Zampini } 135945471136SStefano Zampini ierr = MatIsStructurallySymmetric(matis->A,&local_sym);CHKERRQ(ierr); 136045471136SStefano Zampini ierr = MPIU_Allreduce(&local_sym,flg,1,MPIU_BOOL,MPI_LAND,PetscObjectComm((PetscObject)A));CHKERRQ(ierr); 136145471136SStefano Zampini PetscFunctionReturn(0); 136245471136SStefano Zampini } 136345471136SStefano Zampini 136445471136SStefano Zampini #undef __FUNCT__ 1365b4319ba4SBarry Smith #define __FUNCT__ "MatDestroy_IS" 1366a8116848SStefano Zampini static PetscErrorCode MatDestroy_IS(Mat A) 1367b4319ba4SBarry Smith { 1368dfbe8321SBarry Smith PetscErrorCode ierr; 1369b4319ba4SBarry Smith Mat_IS *b = (Mat_IS*)A->data; 1370b4319ba4SBarry Smith 1371b4319ba4SBarry Smith PetscFunctionBegin; 13726bf464f9SBarry Smith ierr = MatDestroy(&b->A);CHKERRQ(ierr); 1373e176bc59SStefano Zampini ierr = VecScatterDestroy(&b->cctx);CHKERRQ(ierr); 1374e176bc59SStefano Zampini ierr = VecScatterDestroy(&b->rctx);CHKERRQ(ierr); 13756bf464f9SBarry Smith ierr = VecDestroy(&b->x);CHKERRQ(ierr); 13766bf464f9SBarry Smith ierr = VecDestroy(&b->y);CHKERRQ(ierr); 13773fd1c9e7SStefano Zampini ierr = VecDestroy(&b->counter);CHKERRQ(ierr); 1378a8116848SStefano Zampini ierr = ISDestroy(&b->getsub_ris);CHKERRQ(ierr); 1379a8116848SStefano Zampini ierr = ISDestroy(&b->getsub_cis);CHKERRQ(ierr); 1380a8116848SStefano Zampini if (b->sf != b->csf) { 1381a8116848SStefano Zampini ierr = PetscSFDestroy(&b->csf);CHKERRQ(ierr); 1382a8116848SStefano Zampini ierr = PetscFree2(b->csf_rootdata,b->csf_leafdata);CHKERRQ(ierr); 1383a8116848SStefano Zampini } 138428f4e0baSStefano Zampini ierr = PetscSFDestroy(&b->sf);CHKERRQ(ierr); 138528f4e0baSStefano Zampini ierr = PetscFree2(b->sf_rootdata,b->sf_leafdata);CHKERRQ(ierr); 1386bf0cc555SLisandro Dalcin ierr = PetscFree(A->data);CHKERRQ(ierr); 1387dbd8c25aSHong Zhang ierr = PetscObjectChangeTypeName((PetscObject)A,0);CHKERRQ(ierr); 1388bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatISGetLocalMat_C",NULL);CHKERRQ(ierr); 1389b7ce53b6SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatISSetLocalMat_C",NULL);CHKERRQ(ierr); 1390b7ce53b6SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatISGetMPIXAIJ_C",NULL);CHKERRQ(ierr); 13912e1947a5SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatISSetPreallocation_C",NULL);CHKERRQ(ierr); 1392cf0a3239SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatISSetUpSF_C",NULL);CHKERRQ(ierr); 1393b4319ba4SBarry Smith PetscFunctionReturn(0); 1394b4319ba4SBarry Smith } 1395b4319ba4SBarry Smith 1396b4319ba4SBarry Smith #undef __FUNCT__ 1397b4319ba4SBarry Smith #define __FUNCT__ "MatMult_IS" 1398a8116848SStefano Zampini static PetscErrorCode MatMult_IS(Mat A,Vec x,Vec y) 1399b4319ba4SBarry Smith { 1400dfbe8321SBarry Smith PetscErrorCode ierr; 1401b4319ba4SBarry Smith Mat_IS *is = (Mat_IS*)A->data; 1402b4319ba4SBarry Smith PetscScalar zero = 0.0; 1403b4319ba4SBarry Smith 1404b4319ba4SBarry Smith PetscFunctionBegin; 1405b4319ba4SBarry Smith /* scatter the global vector x into the local work vector */ 1406e176bc59SStefano Zampini ierr = VecScatterBegin(is->cctx,x,is->x,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1407e176bc59SStefano Zampini ierr = VecScatterEnd(is->cctx,x,is->x,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1408b4319ba4SBarry Smith 1409b4319ba4SBarry Smith /* multiply the local matrix */ 1410b4319ba4SBarry Smith ierr = MatMult(is->A,is->x,is->y);CHKERRQ(ierr); 1411b4319ba4SBarry Smith 1412b4319ba4SBarry Smith /* scatter product back into global memory */ 14132dcb1b2aSMatthew Knepley ierr = VecSet(y,zero);CHKERRQ(ierr); 1414e176bc59SStefano Zampini ierr = VecScatterBegin(is->rctx,is->y,y,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 1415e176bc59SStefano Zampini ierr = VecScatterEnd(is->rctx,is->y,y,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 1416b4319ba4SBarry Smith PetscFunctionReturn(0); 1417b4319ba4SBarry Smith } 1418b4319ba4SBarry Smith 1419b4319ba4SBarry Smith #undef __FUNCT__ 14202e74eeadSLisandro Dalcin #define __FUNCT__ "MatMultAdd_IS" 1421a8116848SStefano Zampini static PetscErrorCode MatMultAdd_IS(Mat A,Vec v1,Vec v2,Vec v3) 14222e74eeadSLisandro Dalcin { 1423650997f4SStefano Zampini Vec temp_vec; 14242e74eeadSLisandro Dalcin PetscErrorCode ierr; 14252e74eeadSLisandro Dalcin 14262e74eeadSLisandro Dalcin PetscFunctionBegin; /* v3 = v2 + A * v1.*/ 1427650997f4SStefano Zampini if (v3 != v2) { 1428650997f4SStefano Zampini ierr = MatMult(A,v1,v3);CHKERRQ(ierr); 1429650997f4SStefano Zampini ierr = VecAXPY(v3,1.0,v2);CHKERRQ(ierr); 1430650997f4SStefano Zampini } else { 1431650997f4SStefano Zampini ierr = VecDuplicate(v2,&temp_vec);CHKERRQ(ierr); 1432650997f4SStefano Zampini ierr = MatMult(A,v1,temp_vec);CHKERRQ(ierr); 1433650997f4SStefano Zampini ierr = VecAXPY(temp_vec,1.0,v2);CHKERRQ(ierr); 1434650997f4SStefano Zampini ierr = VecCopy(temp_vec,v3);CHKERRQ(ierr); 1435650997f4SStefano Zampini ierr = VecDestroy(&temp_vec);CHKERRQ(ierr); 1436650997f4SStefano Zampini } 14372e74eeadSLisandro Dalcin PetscFunctionReturn(0); 14382e74eeadSLisandro Dalcin } 14392e74eeadSLisandro Dalcin 14402e74eeadSLisandro Dalcin #undef __FUNCT__ 14412e74eeadSLisandro Dalcin #define __FUNCT__ "MatMultTranspose_IS" 1442a8116848SStefano Zampini static PetscErrorCode MatMultTranspose_IS(Mat A,Vec y,Vec x) 14432e74eeadSLisandro Dalcin { 14442e74eeadSLisandro Dalcin Mat_IS *is = (Mat_IS*)A->data; 14452e74eeadSLisandro Dalcin PetscErrorCode ierr; 14462e74eeadSLisandro Dalcin 1447e176bc59SStefano Zampini PetscFunctionBegin; 14482e74eeadSLisandro Dalcin /* scatter the global vector x into the local work vector */ 1449e176bc59SStefano Zampini ierr = VecScatterBegin(is->rctx,y,is->y,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1450e176bc59SStefano Zampini ierr = VecScatterEnd(is->rctx,y,is->y,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 14512e74eeadSLisandro Dalcin 14522e74eeadSLisandro Dalcin /* multiply the local matrix */ 1453e176bc59SStefano Zampini ierr = MatMultTranspose(is->A,is->y,is->x);CHKERRQ(ierr); 14542e74eeadSLisandro Dalcin 14552e74eeadSLisandro Dalcin /* scatter product back into global vector */ 1456e176bc59SStefano Zampini ierr = VecSet(x,0);CHKERRQ(ierr); 1457e176bc59SStefano Zampini ierr = VecScatterBegin(is->cctx,is->x,x,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 1458e176bc59SStefano Zampini ierr = VecScatterEnd(is->cctx,is->x,x,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 14592e74eeadSLisandro Dalcin PetscFunctionReturn(0); 14602e74eeadSLisandro Dalcin } 14612e74eeadSLisandro Dalcin 14622e74eeadSLisandro Dalcin #undef __FUNCT__ 14632e74eeadSLisandro Dalcin #define __FUNCT__ "MatMultTransposeAdd_IS" 1464a8116848SStefano Zampini static PetscErrorCode MatMultTransposeAdd_IS(Mat A,Vec v1,Vec v2,Vec v3) 14652e74eeadSLisandro Dalcin { 1466650997f4SStefano Zampini Vec temp_vec; 14672e74eeadSLisandro Dalcin PetscErrorCode ierr; 14682e74eeadSLisandro Dalcin 14692e74eeadSLisandro Dalcin PetscFunctionBegin; /* v3 = v2 + A' * v1.*/ 1470650997f4SStefano Zampini if (v3 != v2) { 1471650997f4SStefano Zampini ierr = MatMultTranspose(A,v1,v3);CHKERRQ(ierr); 1472650997f4SStefano Zampini ierr = VecAXPY(v3,1.0,v2);CHKERRQ(ierr); 1473650997f4SStefano Zampini } else { 1474650997f4SStefano Zampini ierr = VecDuplicate(v2,&temp_vec);CHKERRQ(ierr); 1475650997f4SStefano Zampini ierr = MatMultTranspose(A,v1,temp_vec);CHKERRQ(ierr); 1476650997f4SStefano Zampini ierr = VecAXPY(temp_vec,1.0,v2);CHKERRQ(ierr); 1477650997f4SStefano Zampini ierr = VecCopy(temp_vec,v3);CHKERRQ(ierr); 1478650997f4SStefano Zampini ierr = VecDestroy(&temp_vec);CHKERRQ(ierr); 1479650997f4SStefano Zampini } 14802e74eeadSLisandro Dalcin PetscFunctionReturn(0); 14812e74eeadSLisandro Dalcin } 14822e74eeadSLisandro Dalcin 14832e74eeadSLisandro Dalcin #undef __FUNCT__ 1484b4319ba4SBarry Smith #define __FUNCT__ "MatView_IS" 1485a8116848SStefano Zampini static PetscErrorCode MatView_IS(Mat A,PetscViewer viewer) 1486b4319ba4SBarry Smith { 1487b4319ba4SBarry Smith Mat_IS *a = (Mat_IS*)A->data; 1488dfbe8321SBarry Smith PetscErrorCode ierr; 1489b4319ba4SBarry Smith PetscViewer sviewer; 1490ee2491ecSStefano Zampini PetscBool isascii,view = PETSC_TRUE; 1491b4319ba4SBarry Smith 1492b4319ba4SBarry Smith PetscFunctionBegin; 1493ee2491ecSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isascii);CHKERRQ(ierr); 1494ee2491ecSStefano Zampini if (isascii) { 1495ee2491ecSStefano Zampini PetscViewerFormat format; 1496ee2491ecSStefano Zampini 1497ee2491ecSStefano Zampini ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr); 1498ee2491ecSStefano Zampini if (format == PETSC_VIEWER_ASCII_INFO) view = PETSC_FALSE; 1499ee2491ecSStefano Zampini } 1500ee2491ecSStefano Zampini if (!view) PetscFunctionReturn(0); 15013f08860eSBarry Smith ierr = PetscViewerGetSubViewer(viewer,PETSC_COMM_SELF,&sviewer);CHKERRQ(ierr); 1502b4319ba4SBarry Smith ierr = MatView(a->A,sviewer);CHKERRQ(ierr); 15033f08860eSBarry Smith ierr = PetscViewerRestoreSubViewer(viewer,PETSC_COMM_SELF,&sviewer);CHKERRQ(ierr); 15046e520ac8SStefano Zampini ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 1505b4319ba4SBarry Smith PetscFunctionReturn(0); 1506b4319ba4SBarry Smith } 1507b4319ba4SBarry Smith 1508b4319ba4SBarry Smith #undef __FUNCT__ 1509b4319ba4SBarry Smith #define __FUNCT__ "MatSetLocalToGlobalMapping_IS" 1510a8116848SStefano Zampini static PetscErrorCode MatSetLocalToGlobalMapping_IS(Mat A,ISLocalToGlobalMapping rmapping,ISLocalToGlobalMapping cmapping) 1511b4319ba4SBarry Smith { 1512dfbe8321SBarry Smith PetscErrorCode ierr; 1513e176bc59SStefano Zampini PetscInt nr,rbs,nc,cbs; 1514b4319ba4SBarry Smith Mat_IS *is = (Mat_IS*)A->data; 1515b4319ba4SBarry Smith IS from,to; 1516e176bc59SStefano Zampini Vec cglobal,rglobal; 1517b4319ba4SBarry Smith 1518b4319ba4SBarry Smith PetscFunctionBegin; 1519784ac674SJed Brown PetscCheckSameComm(A,1,rmapping,2); 1520e176bc59SStefano Zampini PetscCheckSameComm(A,1,cmapping,3); 15213bbff08aSStefano Zampini /* Destroy any previous data */ 152270cf5478SStefano Zampini ierr = VecDestroy(&is->x);CHKERRQ(ierr); 152370cf5478SStefano Zampini ierr = VecDestroy(&is->y);CHKERRQ(ierr); 15243fd1c9e7SStefano Zampini ierr = VecDestroy(&is->counter);CHKERRQ(ierr); 1525e176bc59SStefano Zampini ierr = VecScatterDestroy(&is->rctx);CHKERRQ(ierr); 1526e176bc59SStefano Zampini ierr = VecScatterDestroy(&is->cctx);CHKERRQ(ierr); 15271c47cb0fSStefano Zampini ierr = MatDestroy(&is->A);CHKERRQ(ierr); 152828f4e0baSStefano Zampini ierr = PetscSFDestroy(&is->sf);CHKERRQ(ierr); 152928f4e0baSStefano Zampini ierr = PetscFree2(is->sf_rootdata,is->sf_leafdata);CHKERRQ(ierr); 15303bbff08aSStefano Zampini 15313bbff08aSStefano Zampini /* Setup Layout and set local to global maps */ 1532fc27028aSStefano Zampini ierr = PetscLayoutSetUp(A->rmap);CHKERRQ(ierr); 1533fc27028aSStefano Zampini ierr = PetscLayoutSetUp(A->cmap);CHKERRQ(ierr); 1534fa7f1dd8SStefano Zampini ierr = PetscLayoutSetISLocalToGlobalMapping(A->rmap,rmapping);CHKERRQ(ierr); 1535fa7f1dd8SStefano Zampini ierr = PetscLayoutSetISLocalToGlobalMapping(A->cmap,cmapping);CHKERRQ(ierr); 1536b4319ba4SBarry Smith 1537b4319ba4SBarry Smith /* Create the local matrix A */ 1538e176bc59SStefano Zampini ierr = ISLocalToGlobalMappingGetSize(rmapping,&nr);CHKERRQ(ierr); 1539e176bc59SStefano Zampini ierr = ISLocalToGlobalMappingGetBlockSize(rmapping,&rbs);CHKERRQ(ierr); 1540e176bc59SStefano Zampini ierr = ISLocalToGlobalMappingGetSize(cmapping,&nc);CHKERRQ(ierr); 1541e176bc59SStefano Zampini ierr = ISLocalToGlobalMappingGetBlockSize(cmapping,&cbs);CHKERRQ(ierr); 1542f69a0ea3SMatthew Knepley ierr = MatCreate(PETSC_COMM_SELF,&is->A);CHKERRQ(ierr); 1543e176bc59SStefano Zampini ierr = MatSetType(is->A,MATAIJ);CHKERRQ(ierr); 1544e176bc59SStefano Zampini ierr = MatSetSizes(is->A,nr,nc,nr,nc);CHKERRQ(ierr); 1545e176bc59SStefano Zampini ierr = MatSetBlockSizes(is->A,rbs,cbs);CHKERRQ(ierr); 1546ff130e51SJed Brown ierr = MatSetOptionsPrefix(is->A,((PetscObject)A)->prefix);CHKERRQ(ierr); 1547ff130e51SJed Brown ierr = MatAppendOptionsPrefix(is->A,"is_");CHKERRQ(ierr); 1548b4319ba4SBarry Smith ierr = MatSetFromOptions(is->A);CHKERRQ(ierr); 1549b4319ba4SBarry Smith 1550f26d0771SStefano Zampini if (!is->islocalref) { /* setup scatters and local vectors for MatMult */ 1551b4319ba4SBarry Smith /* Create the local work vectors */ 15523bbff08aSStefano Zampini ierr = MatCreateVecs(is->A,&is->x,&is->y);CHKERRQ(ierr); 1553b4319ba4SBarry Smith 1554e176bc59SStefano Zampini /* setup the global to local scatters */ 1555e176bc59SStefano Zampini ierr = MatCreateVecs(A,&cglobal,&rglobal);CHKERRQ(ierr); 1556e176bc59SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,nr,0,1,&to);CHKERRQ(ierr); 1557784ac674SJed Brown ierr = ISLocalToGlobalMappingApplyIS(rmapping,to,&from);CHKERRQ(ierr); 1558e176bc59SStefano Zampini ierr = VecScatterCreate(rglobal,from,is->y,to,&is->rctx);CHKERRQ(ierr); 1559e176bc59SStefano Zampini if (rmapping != cmapping) { 1560e176bc59SStefano Zampini ierr = ISDestroy(&to);CHKERRQ(ierr); 1561e176bc59SStefano Zampini ierr = ISDestroy(&from);CHKERRQ(ierr); 1562e176bc59SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,nc,0,1,&to);CHKERRQ(ierr); 1563e176bc59SStefano Zampini ierr = ISLocalToGlobalMappingApplyIS(cmapping,to,&from);CHKERRQ(ierr); 1564e176bc59SStefano Zampini ierr = VecScatterCreate(cglobal,from,is->x,to,&is->cctx);CHKERRQ(ierr); 1565e176bc59SStefano Zampini } else { 1566e176bc59SStefano Zampini ierr = PetscObjectReference((PetscObject)is->rctx);CHKERRQ(ierr); 1567e176bc59SStefano Zampini is->cctx = is->rctx; 1568e176bc59SStefano Zampini } 15693fd1c9e7SStefano Zampini 15703fd1c9e7SStefano Zampini /* interface counter vector (local) */ 15713fd1c9e7SStefano Zampini ierr = VecDuplicate(is->y,&is->counter);CHKERRQ(ierr); 15723fd1c9e7SStefano Zampini ierr = VecSet(is->y,1.);CHKERRQ(ierr); 15733fd1c9e7SStefano Zampini ierr = VecScatterBegin(is->rctx,is->y,rglobal,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 15743fd1c9e7SStefano Zampini ierr = VecScatterEnd(is->rctx,is->y,rglobal,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 15753fd1c9e7SStefano Zampini ierr = VecScatterBegin(is->rctx,rglobal,is->counter,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 15763fd1c9e7SStefano Zampini ierr = VecScatterEnd(is->rctx,rglobal,is->counter,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 15773fd1c9e7SStefano Zampini 15783fd1c9e7SStefano Zampini /* free workspace */ 1579e176bc59SStefano Zampini ierr = VecDestroy(&rglobal);CHKERRQ(ierr); 1580e176bc59SStefano Zampini ierr = VecDestroy(&cglobal);CHKERRQ(ierr); 15816bf464f9SBarry Smith ierr = ISDestroy(&to);CHKERRQ(ierr); 15826bf464f9SBarry Smith ierr = ISDestroy(&from);CHKERRQ(ierr); 1583f26d0771SStefano Zampini } 15849c0b00dbSStefano Zampini ierr = MatSetUp(A);CHKERRQ(ierr); 1585b4319ba4SBarry Smith PetscFunctionReturn(0); 1586b4319ba4SBarry Smith } 1587b4319ba4SBarry Smith 15882e74eeadSLisandro Dalcin #undef __FUNCT__ 15892e74eeadSLisandro Dalcin #define __FUNCT__ "MatSetValues_IS" 1590a8116848SStefano Zampini static PetscErrorCode MatSetValues_IS(Mat mat, PetscInt m,const PetscInt *rows, PetscInt n,const PetscInt *cols, const PetscScalar *values, InsertMode addv) 15912e74eeadSLisandro Dalcin { 15922e74eeadSLisandro Dalcin Mat_IS *is = (Mat_IS*)mat->data; 15932e74eeadSLisandro Dalcin PetscErrorCode ierr; 159497563a80SStefano Zampini #if defined(PETSC_USE_DEBUG) 159597563a80SStefano Zampini PetscInt i,zm,zn; 159697563a80SStefano Zampini #endif 1597f26d0771SStefano Zampini PetscInt rows_l[MATIS_MAX_ENTRIES_INSERTION],cols_l[MATIS_MAX_ENTRIES_INSERTION]; 15982e74eeadSLisandro Dalcin 15992e74eeadSLisandro Dalcin PetscFunctionBegin; 16002e74eeadSLisandro Dalcin #if defined(PETSC_USE_DEBUG) 1601f26d0771SStefano 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); 160297563a80SStefano Zampini /* count negative indices */ 160397563a80SStefano Zampini for (i=0,zm=0;i<m;i++) if (rows[i] < 0) zm++; 160497563a80SStefano Zampini for (i=0,zn=0;i<n;i++) if (cols[i] < 0) zn++; 16052e74eeadSLisandro Dalcin #endif 160697563a80SStefano Zampini ierr = ISGlobalToLocalMappingApply(mat->rmap->mapping,IS_GTOLM_MASK,m,rows,&m,rows_l);CHKERRQ(ierr); 160797563a80SStefano Zampini ierr = ISGlobalToLocalMappingApply(mat->cmap->mapping,IS_GTOLM_MASK,n,cols,&n,cols_l);CHKERRQ(ierr); 160897563a80SStefano Zampini #if defined(PETSC_USE_DEBUG) 160997563a80SStefano Zampini /* count negative indices (should be the same as before) */ 161097563a80SStefano Zampini for (i=0;i<m;i++) if (rows_l[i] < 0) zm--; 161197563a80SStefano Zampini for (i=0;i<n;i++) if (cols_l[i] < 0) zn--; 161297563a80SStefano 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"); 161397563a80SStefano 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"); 161497563a80SStefano Zampini #endif 16152e74eeadSLisandro Dalcin ierr = MatSetValues(is->A,m,rows_l,n,cols_l,values,addv);CHKERRQ(ierr); 16162e74eeadSLisandro Dalcin PetscFunctionReturn(0); 16172e74eeadSLisandro Dalcin } 16182e74eeadSLisandro Dalcin 1619b4319ba4SBarry Smith #undef __FUNCT__ 162097563a80SStefano Zampini #define __FUNCT__ "MatSetValuesBlocked_IS" 1621a8116848SStefano Zampini static PetscErrorCode MatSetValuesBlocked_IS(Mat mat, PetscInt m,const PetscInt *rows, PetscInt n,const PetscInt *cols, const PetscScalar *values, InsertMode addv) 162297563a80SStefano Zampini { 162397563a80SStefano Zampini Mat_IS *is = (Mat_IS*)mat->data; 162497563a80SStefano Zampini PetscErrorCode ierr; 162597563a80SStefano Zampini #if defined(PETSC_USE_DEBUG) 162697563a80SStefano Zampini PetscInt i,zm,zn; 162797563a80SStefano Zampini #endif 1628f26d0771SStefano Zampini PetscInt rows_l[MATIS_MAX_ENTRIES_INSERTION],cols_l[MATIS_MAX_ENTRIES_INSERTION]; 162997563a80SStefano Zampini 163097563a80SStefano Zampini PetscFunctionBegin; 163197563a80SStefano Zampini #if defined(PETSC_USE_DEBUG) 1632f26d0771SStefano 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); 163397563a80SStefano Zampini /* count negative indices */ 163497563a80SStefano Zampini for (i=0,zm=0;i<m;i++) if (rows[i] < 0) zm++; 163597563a80SStefano Zampini for (i=0,zn=0;i<n;i++) if (cols[i] < 0) zn++; 163697563a80SStefano Zampini #endif 163797563a80SStefano Zampini ierr = ISGlobalToLocalMappingApplyBlock(mat->rmap->mapping,IS_GTOLM_MASK,m,rows,&m,rows_l);CHKERRQ(ierr); 163897563a80SStefano Zampini ierr = ISGlobalToLocalMappingApplyBlock(mat->cmap->mapping,IS_GTOLM_MASK,n,cols,&n,cols_l);CHKERRQ(ierr); 163997563a80SStefano Zampini #if defined(PETSC_USE_DEBUG) 164097563a80SStefano Zampini /* count negative indices (should be the same as before) */ 164197563a80SStefano Zampini for (i=0;i<m;i++) if (rows_l[i] < 0) zm--; 164297563a80SStefano Zampini for (i=0;i<n;i++) if (cols_l[i] < 0) zn--; 164397563a80SStefano 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"); 164497563a80SStefano 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"); 164597563a80SStefano Zampini #endif 164697563a80SStefano Zampini ierr = MatSetValuesBlocked(is->A,m,rows_l,n,cols_l,values,addv);CHKERRQ(ierr); 164797563a80SStefano Zampini PetscFunctionReturn(0); 164897563a80SStefano Zampini } 164997563a80SStefano Zampini 165097563a80SStefano Zampini #undef __FUNCT__ 1651b4319ba4SBarry Smith #define __FUNCT__ "MatSetValuesLocal_IS" 1652a8116848SStefano Zampini static PetscErrorCode MatSetValuesLocal_IS(Mat A,PetscInt m,const PetscInt *rows, PetscInt n,const PetscInt *cols,const PetscScalar *values,InsertMode addv) 1653b4319ba4SBarry Smith { 1654dfbe8321SBarry Smith PetscErrorCode ierr; 1655b4319ba4SBarry Smith Mat_IS *is = (Mat_IS*)A->data; 1656b4319ba4SBarry Smith 1657b4319ba4SBarry Smith PetscFunctionBegin; 1658b4319ba4SBarry Smith ierr = MatSetValues(is->A,m,rows,n,cols,values,addv);CHKERRQ(ierr); 1659b4319ba4SBarry Smith PetscFunctionReturn(0); 1660b4319ba4SBarry Smith } 1661b4319ba4SBarry Smith 1662b4319ba4SBarry Smith #undef __FUNCT__ 1663f0006bf2SLisandro Dalcin #define __FUNCT__ "MatSetValuesBlockedLocal_IS" 1664a8116848SStefano Zampini static PetscErrorCode MatSetValuesBlockedLocal_IS(Mat A,PetscInt m,const PetscInt *rows, PetscInt n,const PetscInt *cols,const PetscScalar *values,InsertMode addv) 1665f0006bf2SLisandro Dalcin { 1666f0006bf2SLisandro Dalcin PetscErrorCode ierr; 1667f0006bf2SLisandro Dalcin Mat_IS *is = (Mat_IS*)A->data; 1668f0006bf2SLisandro Dalcin 1669f0006bf2SLisandro Dalcin PetscFunctionBegin; 1670f0006bf2SLisandro Dalcin ierr = MatSetValuesBlocked(is->A,m,rows,n,cols,values,addv);CHKERRQ(ierr); 1671f0006bf2SLisandro Dalcin PetscFunctionReturn(0); 1672f0006bf2SLisandro Dalcin } 1673f0006bf2SLisandro Dalcin 1674f0006bf2SLisandro Dalcin #undef __FUNCT__ 1675f0ae7da4SStefano Zampini #define __FUNCT__ "MatISZeroRowsColumnsLocal_Private" 1676f0ae7da4SStefano Zampini static PetscErrorCode MatISZeroRowsColumnsLocal_Private(Mat A,PetscInt n,const PetscInt rows[],PetscScalar diag,PetscBool columns) 16772e74eeadSLisandro Dalcin { 1678f0ae7da4SStefano Zampini Mat_IS *is = (Mat_IS*)A->data; 16792e74eeadSLisandro Dalcin PetscErrorCode ierr; 16802e74eeadSLisandro Dalcin 16812e74eeadSLisandro Dalcin PetscFunctionBegin; 1682f0ae7da4SStefano Zampini if (!n) { 1683f0ae7da4SStefano Zampini is->pure_neumann = PETSC_TRUE; 1684f0ae7da4SStefano Zampini } else { 1685f0ae7da4SStefano Zampini PetscInt i; 1686f0ae7da4SStefano Zampini is->pure_neumann = PETSC_FALSE; 1687f0ae7da4SStefano Zampini 1688f0ae7da4SStefano Zampini if (columns) { 1689f0ae7da4SStefano Zampini ierr = MatZeroRowsColumns(is->A,n,rows,diag,0,0);CHKERRQ(ierr); 1690f0ae7da4SStefano Zampini } else { 1691f0ae7da4SStefano Zampini ierr = MatZeroRows(is->A,n,rows,diag,0,0);CHKERRQ(ierr); 16922e74eeadSLisandro Dalcin } 1693f0ae7da4SStefano Zampini if (diag != 0.) { 1694f0ae7da4SStefano Zampini const PetscScalar *array; 1695f0ae7da4SStefano Zampini ierr = VecGetArrayRead(is->counter,&array);CHKERRQ(ierr); 1696f0ae7da4SStefano Zampini for (i=0; i<n; i++) { 1697f0ae7da4SStefano Zampini ierr = MatSetValue(is->A,rows[i],rows[i],diag/(array[rows[i]]),INSERT_VALUES);CHKERRQ(ierr); 1698f0ae7da4SStefano Zampini } 1699f0ae7da4SStefano Zampini ierr = VecRestoreArrayRead(is->counter,&array);CHKERRQ(ierr); 1700f0ae7da4SStefano Zampini } 1701f0ae7da4SStefano Zampini ierr = MatAssemblyBegin(is->A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1702f0ae7da4SStefano Zampini ierr = MatAssemblyEnd(is->A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1703f0ae7da4SStefano Zampini } 17042e74eeadSLisandro Dalcin PetscFunctionReturn(0); 17052e74eeadSLisandro Dalcin } 17062e74eeadSLisandro Dalcin 17072e74eeadSLisandro Dalcin #undef __FUNCT__ 1708f0ae7da4SStefano Zampini #define __FUNCT__ "MatZeroRowsColumns_Private_IS" 1709f0ae7da4SStefano Zampini static PetscErrorCode MatZeroRowsColumns_Private_IS(Mat A,PetscInt n,const PetscInt rows[],PetscScalar diag,Vec x,Vec b,PetscBool columns) 1710b4319ba4SBarry Smith { 17116e520ac8SStefano Zampini Mat_IS *matis = (Mat_IS*)A->data; 17126e520ac8SStefano Zampini PetscInt nr,nl,len,i; 17136e520ac8SStefano Zampini PetscInt *lrows; 1714dfbe8321SBarry Smith PetscErrorCode ierr; 1715b4319ba4SBarry Smith 1716b4319ba4SBarry Smith PetscFunctionBegin; 1717f0ae7da4SStefano Zampini #if defined(PETSC_USE_DEBUG) 1718f0ae7da4SStefano Zampini if (columns || diag != 0. || (x && b)) { 1719f0ae7da4SStefano Zampini PetscBool cong; 1720f0ae7da4SStefano Zampini ierr = PetscLayoutCompare(A->rmap,A->cmap,&cong);CHKERRQ(ierr); 1721f0ae7da4SStefano 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"); 1722f0ae7da4SStefano 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"); 1723f0ae7da4SStefano Zampini if (!cong && x && b) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"A->rmap and A->cmap need to be congruent"); 1724b4319ba4SBarry Smith } 1725f0ae7da4SStefano Zampini #endif 17266e520ac8SStefano Zampini /* get locally owned rows */ 1727f0ae7da4SStefano Zampini ierr = PetscLayoutMapLocal_Private(A->rmap,n,rows,&len,&lrows,NULL);CHKERRQ(ierr); 17286e520ac8SStefano Zampini /* fix right hand side if needed */ 17296e520ac8SStefano Zampini if (x && b) { 17306e520ac8SStefano Zampini const PetscScalar *xx; 17316e520ac8SStefano Zampini PetscScalar *bb; 17322205254eSKarl Rupp 17336e520ac8SStefano Zampini ierr = VecGetArrayRead(x, &xx);CHKERRQ(ierr); 17346e520ac8SStefano Zampini ierr = VecGetArray(b, &bb);CHKERRQ(ierr); 17356e520ac8SStefano Zampini for (i=0;i<len;++i) bb[lrows[i]] = diag*xx[lrows[i]]; 17366e520ac8SStefano Zampini ierr = VecRestoreArrayRead(x, &xx);CHKERRQ(ierr); 17376e520ac8SStefano Zampini ierr = VecRestoreArray(b, &bb);CHKERRQ(ierr); 1738b4319ba4SBarry Smith } 17396e520ac8SStefano Zampini /* get rows associated to the local matrices */ 17403d996552SStefano Zampini ierr = MatISSetUpSF(A);CHKERRQ(ierr); 17416e520ac8SStefano Zampini ierr = MatGetSize(matis->A,&nl,NULL);CHKERRQ(ierr); 17426e520ac8SStefano Zampini ierr = PetscMemzero(matis->sf_leafdata,nl*sizeof(PetscInt));CHKERRQ(ierr); 17436e520ac8SStefano Zampini ierr = PetscMemzero(matis->sf_rootdata,A->rmap->n*sizeof(PetscInt));CHKERRQ(ierr); 17446e520ac8SStefano Zampini for (i=0;i<len;i++) matis->sf_rootdata[lrows[i]] = 1; 17456e520ac8SStefano Zampini ierr = PetscFree(lrows);CHKERRQ(ierr); 17466e520ac8SStefano Zampini ierr = PetscSFBcastBegin(matis->sf,MPIU_INT,matis->sf_rootdata,matis->sf_leafdata);CHKERRQ(ierr); 17476e520ac8SStefano Zampini ierr = PetscSFBcastEnd(matis->sf,MPIU_INT,matis->sf_rootdata,matis->sf_leafdata);CHKERRQ(ierr); 17486e520ac8SStefano Zampini ierr = PetscMalloc1(nl,&lrows);CHKERRQ(ierr); 17496e520ac8SStefano Zampini for (i=0,nr=0;i<nl;i++) if (matis->sf_leafdata[i]) lrows[nr++] = i; 1750f0ae7da4SStefano Zampini ierr = MatISZeroRowsColumnsLocal_Private(A,nr,lrows,diag,columns);CHKERRQ(ierr); 17516e520ac8SStefano Zampini ierr = PetscFree(lrows);CHKERRQ(ierr); 1752b4319ba4SBarry Smith PetscFunctionReturn(0); 1753b4319ba4SBarry Smith } 1754b4319ba4SBarry Smith 1755b4319ba4SBarry Smith #undef __FUNCT__ 1756f0ae7da4SStefano Zampini #define __FUNCT__ "MatZeroRows_IS" 1757f0ae7da4SStefano Zampini static PetscErrorCode MatZeroRows_IS(Mat A,PetscInt n,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 1758b4319ba4SBarry Smith { 1759b4319ba4SBarry Smith PetscErrorCode ierr; 1760b4319ba4SBarry Smith 1761b4319ba4SBarry Smith PetscFunctionBegin; 1762f0ae7da4SStefano Zampini ierr = MatZeroRowsColumns_Private_IS(A,n,rows,diag,x,b,PETSC_FALSE);CHKERRQ(ierr); 1763f0ae7da4SStefano Zampini PetscFunctionReturn(0); 1764f0ae7da4SStefano Zampini } 1765b4319ba4SBarry Smith 1766f0ae7da4SStefano Zampini #undef __FUNCT__ 1767f0ae7da4SStefano Zampini #define __FUNCT__ "MatZeroRowsColumns_IS" 1768f0ae7da4SStefano Zampini static PetscErrorCode MatZeroRowsColumns_IS(Mat A,PetscInt n,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 1769f0ae7da4SStefano Zampini { 1770f0ae7da4SStefano Zampini PetscErrorCode ierr; 1771f0ae7da4SStefano Zampini 1772f0ae7da4SStefano Zampini PetscFunctionBegin; 1773f0ae7da4SStefano Zampini ierr = MatZeroRowsColumns_Private_IS(A,n,rows,diag,x,b,PETSC_TRUE);CHKERRQ(ierr); 1774b4319ba4SBarry Smith PetscFunctionReturn(0); 1775b4319ba4SBarry Smith } 1776b4319ba4SBarry Smith 1777b4319ba4SBarry Smith #undef __FUNCT__ 1778b4319ba4SBarry Smith #define __FUNCT__ "MatAssemblyBegin_IS" 1779a8116848SStefano Zampini static PetscErrorCode MatAssemblyBegin_IS(Mat A,MatAssemblyType type) 1780b4319ba4SBarry Smith { 1781b4319ba4SBarry Smith Mat_IS *is = (Mat_IS*)A->data; 1782dfbe8321SBarry Smith PetscErrorCode ierr; 1783b4319ba4SBarry Smith 1784b4319ba4SBarry Smith PetscFunctionBegin; 1785b4319ba4SBarry Smith ierr = MatAssemblyBegin(is->A,type);CHKERRQ(ierr); 1786b4319ba4SBarry Smith PetscFunctionReturn(0); 1787b4319ba4SBarry Smith } 1788b4319ba4SBarry Smith 1789b4319ba4SBarry Smith #undef __FUNCT__ 1790b4319ba4SBarry Smith #define __FUNCT__ "MatAssemblyEnd_IS" 1791a8116848SStefano Zampini static PetscErrorCode MatAssemblyEnd_IS(Mat A,MatAssemblyType type) 1792b4319ba4SBarry Smith { 1793b4319ba4SBarry Smith Mat_IS *is = (Mat_IS*)A->data; 1794dfbe8321SBarry Smith PetscErrorCode ierr; 1795b4319ba4SBarry Smith 1796b4319ba4SBarry Smith PetscFunctionBegin; 1797b4319ba4SBarry Smith ierr = MatAssemblyEnd(is->A,type);CHKERRQ(ierr); 1798b4319ba4SBarry Smith PetscFunctionReturn(0); 1799b4319ba4SBarry Smith } 1800b4319ba4SBarry Smith 1801b4319ba4SBarry Smith #undef __FUNCT__ 1802b4319ba4SBarry Smith #define __FUNCT__ "MatISGetLocalMat_IS" 1803a8116848SStefano Zampini static PetscErrorCode MatISGetLocalMat_IS(Mat mat,Mat *local) 1804b4319ba4SBarry Smith { 1805b4319ba4SBarry Smith Mat_IS *is = (Mat_IS*)mat->data; 1806b4319ba4SBarry Smith 1807b4319ba4SBarry Smith PetscFunctionBegin; 1808b4319ba4SBarry Smith *local = is->A; 1809b4319ba4SBarry Smith PetscFunctionReturn(0); 1810b4319ba4SBarry Smith } 1811b4319ba4SBarry Smith 1812b4319ba4SBarry Smith #undef __FUNCT__ 1813b4319ba4SBarry Smith #define __FUNCT__ "MatISGetLocalMat" 1814b4319ba4SBarry Smith /*@ 1815b4319ba4SBarry Smith MatISGetLocalMat - Gets the local matrix stored inside a MATIS matrix. 1816b4319ba4SBarry Smith 1817b4319ba4SBarry Smith Input Parameter: 1818b4319ba4SBarry Smith . mat - the matrix 1819b4319ba4SBarry Smith 1820b4319ba4SBarry Smith Output Parameter: 1821eb82efa4SStefano Zampini . local - the local matrix 1822b4319ba4SBarry Smith 1823b4319ba4SBarry Smith Level: advanced 1824b4319ba4SBarry Smith 1825b4319ba4SBarry Smith Notes: 1826b4319ba4SBarry Smith This can be called if you have precomputed the nonzero structure of the 1827b4319ba4SBarry Smith matrix and want to provide it to the inner matrix object to improve the performance 1828b4319ba4SBarry Smith of the MatSetValues() operation. 1829b4319ba4SBarry Smith 1830b4319ba4SBarry Smith .seealso: MATIS 1831b4319ba4SBarry Smith @*/ 18327087cfbeSBarry Smith PetscErrorCode MatISGetLocalMat(Mat mat,Mat *local) 1833b4319ba4SBarry Smith { 18344ac538c5SBarry Smith PetscErrorCode ierr; 1835b4319ba4SBarry Smith 1836b4319ba4SBarry Smith PetscFunctionBegin; 18370700a824SBarry Smith PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1838b4319ba4SBarry Smith PetscValidPointer(local,2); 18394ac538c5SBarry Smith ierr = PetscUseMethod(mat,"MatISGetLocalMat_C",(Mat,Mat*),(mat,local));CHKERRQ(ierr); 1840b4319ba4SBarry Smith PetscFunctionReturn(0); 1841b4319ba4SBarry Smith } 1842b4319ba4SBarry Smith 18433b03a366Sstefano_zampini #undef __FUNCT__ 18443b03a366Sstefano_zampini #define __FUNCT__ "MatISSetLocalMat_IS" 1845a8116848SStefano Zampini static PetscErrorCode MatISSetLocalMat_IS(Mat mat,Mat local) 18463b03a366Sstefano_zampini { 18473b03a366Sstefano_zampini Mat_IS *is = (Mat_IS*)mat->data; 18483b03a366Sstefano_zampini PetscInt nrows,ncols,orows,ocols; 18493b03a366Sstefano_zampini PetscErrorCode ierr; 18503b03a366Sstefano_zampini 18513b03a366Sstefano_zampini PetscFunctionBegin; 18524e4c7dbeSStefano Zampini if (is->A) { 18533b03a366Sstefano_zampini ierr = MatGetSize(is->A,&orows,&ocols);CHKERRQ(ierr); 18543b03a366Sstefano_zampini ierr = MatGetSize(local,&nrows,&ncols);CHKERRQ(ierr); 1855f0ae7da4SStefano 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); 18564e4c7dbeSStefano Zampini } 18573b03a366Sstefano_zampini ierr = PetscObjectReference((PetscObject)local);CHKERRQ(ierr); 18583b03a366Sstefano_zampini ierr = MatDestroy(&is->A);CHKERRQ(ierr); 18593b03a366Sstefano_zampini is->A = local; 18603b03a366Sstefano_zampini PetscFunctionReturn(0); 18613b03a366Sstefano_zampini } 18623b03a366Sstefano_zampini 18633b03a366Sstefano_zampini #undef __FUNCT__ 18643b03a366Sstefano_zampini #define __FUNCT__ "MatISSetLocalMat" 18653b03a366Sstefano_zampini /*@ 1866eb82efa4SStefano Zampini MatISSetLocalMat - Replace the local matrix stored inside a MATIS object. 18673b03a366Sstefano_zampini 18683b03a366Sstefano_zampini Input Parameter: 18693b03a366Sstefano_zampini . mat - the matrix 1870eb82efa4SStefano Zampini . local - the local matrix 18713b03a366Sstefano_zampini 18723b03a366Sstefano_zampini Output Parameter: 18733b03a366Sstefano_zampini 18743b03a366Sstefano_zampini Level: advanced 18753b03a366Sstefano_zampini 18763b03a366Sstefano_zampini Notes: 18773b03a366Sstefano_zampini This can be called if you have precomputed the local matrix and 18783b03a366Sstefano_zampini want to provide it to the matrix object MATIS. 18793b03a366Sstefano_zampini 18803b03a366Sstefano_zampini .seealso: MATIS 18813b03a366Sstefano_zampini @*/ 18823b03a366Sstefano_zampini PetscErrorCode MatISSetLocalMat(Mat mat,Mat local) 18833b03a366Sstefano_zampini { 18843b03a366Sstefano_zampini PetscErrorCode ierr; 18853b03a366Sstefano_zampini 18863b03a366Sstefano_zampini PetscFunctionBegin; 18873b03a366Sstefano_zampini PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1888b7ce53b6SStefano Zampini PetscValidHeaderSpecific(local,MAT_CLASSID,2); 18893b03a366Sstefano_zampini ierr = PetscUseMethod(mat,"MatISSetLocalMat_C",(Mat,Mat),(mat,local));CHKERRQ(ierr); 18903b03a366Sstefano_zampini PetscFunctionReturn(0); 18913b03a366Sstefano_zampini } 18923b03a366Sstefano_zampini 18936726f965SBarry Smith #undef __FUNCT__ 18946726f965SBarry Smith #define __FUNCT__ "MatZeroEntries_IS" 1895a8116848SStefano Zampini static PetscErrorCode MatZeroEntries_IS(Mat A) 18966726f965SBarry Smith { 18976726f965SBarry Smith Mat_IS *a = (Mat_IS*)A->data; 18986726f965SBarry Smith PetscErrorCode ierr; 18996726f965SBarry Smith 19006726f965SBarry Smith PetscFunctionBegin; 19016726f965SBarry Smith ierr = MatZeroEntries(a->A);CHKERRQ(ierr); 19026726f965SBarry Smith PetscFunctionReturn(0); 19036726f965SBarry Smith } 19046726f965SBarry Smith 19056726f965SBarry Smith #undef __FUNCT__ 19062e74eeadSLisandro Dalcin #define __FUNCT__ "MatScale_IS" 1907a8116848SStefano Zampini static PetscErrorCode MatScale_IS(Mat A,PetscScalar a) 19082e74eeadSLisandro Dalcin { 19092e74eeadSLisandro Dalcin Mat_IS *is = (Mat_IS*)A->data; 19102e74eeadSLisandro Dalcin PetscErrorCode ierr; 19112e74eeadSLisandro Dalcin 19122e74eeadSLisandro Dalcin PetscFunctionBegin; 19132e74eeadSLisandro Dalcin ierr = MatScale(is->A,a);CHKERRQ(ierr); 19142e74eeadSLisandro Dalcin PetscFunctionReturn(0); 19152e74eeadSLisandro Dalcin } 19162e74eeadSLisandro Dalcin 19172e74eeadSLisandro Dalcin #undef __FUNCT__ 19182e74eeadSLisandro Dalcin #define __FUNCT__ "MatGetDiagonal_IS" 1919a8116848SStefano Zampini static PetscErrorCode MatGetDiagonal_IS(Mat A, Vec v) 19202e74eeadSLisandro Dalcin { 19212e74eeadSLisandro Dalcin Mat_IS *is = (Mat_IS*)A->data; 19222e74eeadSLisandro Dalcin PetscErrorCode ierr; 19232e74eeadSLisandro Dalcin 19242e74eeadSLisandro Dalcin PetscFunctionBegin; 19252e74eeadSLisandro Dalcin /* get diagonal of the local matrix */ 1926e176bc59SStefano Zampini ierr = MatGetDiagonal(is->A,is->y);CHKERRQ(ierr); 19272e74eeadSLisandro Dalcin 19282e74eeadSLisandro Dalcin /* scatter diagonal back into global vector */ 19292e74eeadSLisandro Dalcin ierr = VecSet(v,0);CHKERRQ(ierr); 1930e176bc59SStefano Zampini ierr = VecScatterBegin(is->rctx,is->y,v,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 1931e176bc59SStefano Zampini ierr = VecScatterEnd(is->rctx,is->y,v,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 19322e74eeadSLisandro Dalcin PetscFunctionReturn(0); 19332e74eeadSLisandro Dalcin } 19342e74eeadSLisandro Dalcin 19352e74eeadSLisandro Dalcin #undef __FUNCT__ 19366726f965SBarry Smith #define __FUNCT__ "MatSetOption_IS" 1937a8116848SStefano Zampini static PetscErrorCode MatSetOption_IS(Mat A,MatOption op,PetscBool flg) 19386726f965SBarry Smith { 19396726f965SBarry Smith Mat_IS *a = (Mat_IS*)A->data; 19406726f965SBarry Smith PetscErrorCode ierr; 19416726f965SBarry Smith 19426726f965SBarry Smith PetscFunctionBegin; 19434e0d8c25SBarry Smith ierr = MatSetOption(a->A,op,flg);CHKERRQ(ierr); 19446726f965SBarry Smith PetscFunctionReturn(0); 19456726f965SBarry Smith } 19466726f965SBarry Smith 1947284134d9SBarry Smith #undef __FUNCT__ 1948f26d0771SStefano Zampini #define __FUNCT__ "MatAXPY_IS" 1949f26d0771SStefano Zampini static PetscErrorCode MatAXPY_IS(Mat Y,PetscScalar a,Mat X,MatStructure str) 1950f26d0771SStefano Zampini { 1951f26d0771SStefano Zampini Mat_IS *y = (Mat_IS*)Y->data; 1952f26d0771SStefano Zampini Mat_IS *x; 1953f26d0771SStefano Zampini #if defined(PETSC_USE_DEBUG) 1954f26d0771SStefano Zampini PetscBool ismatis; 1955f26d0771SStefano Zampini #endif 1956f26d0771SStefano Zampini PetscErrorCode ierr; 1957f26d0771SStefano Zampini 1958f26d0771SStefano Zampini PetscFunctionBegin; 1959f26d0771SStefano Zampini #if defined(PETSC_USE_DEBUG) 1960f26d0771SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)X,MATIS,&ismatis);CHKERRQ(ierr); 1961f26d0771SStefano Zampini if (!ismatis) SETERRQ(PetscObjectComm((PetscObject)Y),PETSC_ERR_SUP,"Cannot call MatAXPY(Y,a,X,str) with X not of type MATIS"); 1962f26d0771SStefano Zampini #endif 1963f26d0771SStefano Zampini x = (Mat_IS*)X->data; 1964f26d0771SStefano Zampini ierr = MatAXPY(y->A,a,x->A,str);CHKERRQ(ierr); 1965f26d0771SStefano Zampini PetscFunctionReturn(0); 1966f26d0771SStefano Zampini } 1967f26d0771SStefano Zampini 1968f26d0771SStefano Zampini #undef __FUNCT__ 1969f26d0771SStefano Zampini #define __FUNCT__ "MatGetLocalSubMatrix_IS" 1970f26d0771SStefano Zampini static PetscErrorCode MatGetLocalSubMatrix_IS(Mat A,IS row,IS col,Mat *submat) 1971f26d0771SStefano Zampini { 1972f26d0771SStefano Zampini Mat lA; 1973f26d0771SStefano Zampini Mat_IS *matis; 1974f26d0771SStefano Zampini ISLocalToGlobalMapping rl2g,cl2g; 1975f26d0771SStefano Zampini IS is; 1976f26d0771SStefano Zampini const PetscInt *rg,*rl; 1977f26d0771SStefano Zampini PetscInt nrg; 1978f26d0771SStefano Zampini PetscInt N,M,nrl,i,*idxs; 1979f26d0771SStefano Zampini PetscErrorCode ierr; 1980f26d0771SStefano Zampini 1981f26d0771SStefano Zampini PetscFunctionBegin; 1982f26d0771SStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(A->rmap->mapping,&rg);CHKERRQ(ierr); 1983f26d0771SStefano Zampini ierr = ISGetLocalSize(row,&nrl);CHKERRQ(ierr); 1984f26d0771SStefano Zampini ierr = ISGetIndices(row,&rl);CHKERRQ(ierr); 1985f26d0771SStefano Zampini ierr = ISLocalToGlobalMappingGetSize(A->rmap->mapping,&nrg);CHKERRQ(ierr); 1986f26d0771SStefano Zampini #if defined(PETSC_USE_DEBUG) 1987f0ae7da4SStefano 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); 1988f26d0771SStefano Zampini #endif 1989f26d0771SStefano Zampini ierr = PetscMalloc1(nrg,&idxs);CHKERRQ(ierr); 1990f26d0771SStefano Zampini /* map from [0,nrl) to row */ 1991f26d0771SStefano Zampini for (i=0;i<nrl;i++) idxs[i] = rl[i]; 1992f26d0771SStefano Zampini #if defined(PETSC_USE_DEBUG) 1993f26d0771SStefano Zampini for (i=nrl;i<nrg;i++) idxs[i] = nrg; 1994f26d0771SStefano Zampini #else 1995f26d0771SStefano Zampini for (i=nrl;i<nrg;i++) idxs[i] = -1; 1996f26d0771SStefano Zampini #endif 1997f26d0771SStefano Zampini ierr = ISRestoreIndices(row,&rl);CHKERRQ(ierr); 1998f26d0771SStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(A->rmap->mapping,&rg);CHKERRQ(ierr); 1999f26d0771SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)A),nrg,idxs,PETSC_OWN_POINTER,&is);CHKERRQ(ierr); 2000f26d0771SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is,&rl2g);CHKERRQ(ierr); 2001f26d0771SStefano Zampini ierr = ISDestroy(&is);CHKERRQ(ierr); 2002f26d0771SStefano Zampini /* compute new l2g map for columns */ 2003f26d0771SStefano Zampini if (col != row || A->rmap->mapping != A->cmap->mapping) { 2004f26d0771SStefano Zampini const PetscInt *cg,*cl; 2005f26d0771SStefano Zampini PetscInt ncg; 2006f26d0771SStefano Zampini PetscInt ncl; 2007f26d0771SStefano Zampini 2008f26d0771SStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(A->cmap->mapping,&cg);CHKERRQ(ierr); 2009f26d0771SStefano Zampini ierr = ISGetLocalSize(col,&ncl);CHKERRQ(ierr); 2010f26d0771SStefano Zampini ierr = ISGetIndices(col,&cl);CHKERRQ(ierr); 2011f26d0771SStefano Zampini ierr = ISLocalToGlobalMappingGetSize(A->cmap->mapping,&ncg);CHKERRQ(ierr); 2012f26d0771SStefano Zampini #if defined(PETSC_USE_DEBUG) 2013f0ae7da4SStefano 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); 2014f26d0771SStefano Zampini #endif 2015f26d0771SStefano Zampini ierr = PetscMalloc1(ncg,&idxs);CHKERRQ(ierr); 2016f26d0771SStefano Zampini /* map from [0,ncl) to col */ 2017f26d0771SStefano Zampini for (i=0;i<ncl;i++) idxs[i] = cl[i]; 2018f26d0771SStefano Zampini #if defined(PETSC_USE_DEBUG) 2019f26d0771SStefano Zampini for (i=ncl;i<ncg;i++) idxs[i] = ncg; 2020f26d0771SStefano Zampini #else 2021f26d0771SStefano Zampini for (i=ncl;i<ncg;i++) idxs[i] = -1; 2022f26d0771SStefano Zampini #endif 2023f26d0771SStefano Zampini ierr = ISRestoreIndices(col,&cl);CHKERRQ(ierr); 2024f26d0771SStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(A->cmap->mapping,&cg);CHKERRQ(ierr); 2025f26d0771SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)A),ncg,idxs,PETSC_OWN_POINTER,&is);CHKERRQ(ierr); 2026f26d0771SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is,&cl2g);CHKERRQ(ierr); 2027f26d0771SStefano Zampini ierr = ISDestroy(&is);CHKERRQ(ierr); 2028f26d0771SStefano Zampini } else { 2029f26d0771SStefano Zampini ierr = PetscObjectReference((PetscObject)rl2g);CHKERRQ(ierr); 2030f26d0771SStefano Zampini cl2g = rl2g; 2031f26d0771SStefano Zampini } 2032f26d0771SStefano Zampini /* create the MATIS submatrix */ 2033f26d0771SStefano Zampini ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr); 2034f26d0771SStefano Zampini ierr = MatCreate(PetscObjectComm((PetscObject)A),submat);CHKERRQ(ierr); 2035f26d0771SStefano Zampini ierr = MatSetSizes(*submat,PETSC_DECIDE,PETSC_DECIDE,M,N);CHKERRQ(ierr); 2036f26d0771SStefano Zampini ierr = MatSetType(*submat,MATIS);CHKERRQ(ierr); 2037b0aa3428SStefano Zampini matis = (Mat_IS*)((*submat)->data); 2038f26d0771SStefano Zampini matis->islocalref = PETSC_TRUE; 2039f26d0771SStefano Zampini ierr = MatSetLocalToGlobalMapping(*submat,rl2g,cl2g);CHKERRQ(ierr); 2040f26d0771SStefano Zampini ierr = MatISGetLocalMat(A,&lA);CHKERRQ(ierr); 2041f26d0771SStefano Zampini ierr = MatISSetLocalMat(*submat,lA);CHKERRQ(ierr); 2042f26d0771SStefano Zampini ierr = MatSetUp(*submat);CHKERRQ(ierr); 2043f26d0771SStefano Zampini ierr = MatAssemblyBegin(*submat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2044f26d0771SStefano Zampini ierr = MatAssemblyEnd(*submat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2045f26d0771SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&rl2g);CHKERRQ(ierr); 2046f26d0771SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&cl2g);CHKERRQ(ierr); 2047f26d0771SStefano Zampini /* remove unsupported ops */ 2048f26d0771SStefano Zampini ierr = PetscMemzero((*submat)->ops,sizeof(struct _MatOps));CHKERRQ(ierr); 2049f26d0771SStefano Zampini (*submat)->ops->destroy = MatDestroy_IS; 2050f26d0771SStefano Zampini (*submat)->ops->setvalueslocal = MatSetValuesLocal_SubMat_IS; 2051f26d0771SStefano Zampini (*submat)->ops->setvaluesblockedlocal = MatSetValuesBlockedLocal_SubMat_IS; 2052f26d0771SStefano Zampini (*submat)->ops->assemblybegin = MatAssemblyBegin_IS; 2053f26d0771SStefano Zampini (*submat)->ops->assemblyend = MatAssemblyEnd_IS; 2054f26d0771SStefano Zampini PetscFunctionReturn(0); 2055f26d0771SStefano Zampini } 2056f26d0771SStefano Zampini 2057f26d0771SStefano Zampini #undef __FUNCT__ 2058284134d9SBarry Smith #define __FUNCT__ "MatCreateIS" 2059284134d9SBarry Smith /*@ 20603c212e90SHong Zhang MatCreateIS - Creates a "process" unassembled matrix, assembled on each 2061284134d9SBarry Smith process but not across processes. 2062284134d9SBarry Smith 2063284134d9SBarry Smith Input Parameters: 2064284134d9SBarry Smith + comm - MPI communicator that will share the matrix 2065e176bc59SStefano Zampini . bs - block size of the matrix 2066df3898eeSBarry Smith . m,n,M,N - local and/or global sizes of the left and right vector used in matrix vector products 2067e176bc59SStefano Zampini . rmap - local to global map for rows 2068e176bc59SStefano Zampini - cmap - local to global map for cols 2069284134d9SBarry Smith 2070284134d9SBarry Smith Output Parameter: 2071284134d9SBarry Smith . A - the resulting matrix 2072284134d9SBarry Smith 20738e6c10adSSatish Balay Level: advanced 20748e6c10adSSatish Balay 20753c212e90SHong Zhang Notes: See MATIS for more details. 20766fdf41d1SStefano Zampini m and n are NOT related to the size of the map; they represent the size of the local parts of the vectors 20776fdf41d1SStefano Zampini used in MatMult operations. The sizes of rmap and cmap define the size of the local matrices. 20783c212e90SHong Zhang If either rmap or cmap are NULL, then the matrix is assumed to be square. 2079284134d9SBarry Smith 2080284134d9SBarry Smith .seealso: MATIS, MatSetLocalToGlobalMapping() 2081284134d9SBarry Smith @*/ 2082e176bc59SStefano Zampini PetscErrorCode MatCreateIS(MPI_Comm comm,PetscInt bs,PetscInt m,PetscInt n,PetscInt M,PetscInt N,ISLocalToGlobalMapping rmap,ISLocalToGlobalMapping cmap,Mat *A) 2083284134d9SBarry Smith { 2084284134d9SBarry Smith PetscErrorCode ierr; 2085284134d9SBarry Smith 2086284134d9SBarry Smith PetscFunctionBegin; 20876fdf41d1SStefano Zampini if (!rmap && !cmap) SETERRQ(comm,PETSC_ERR_USER,"You need to provide at least one of the mappings"); 2088284134d9SBarry Smith ierr = MatCreate(comm,A);CHKERRQ(ierr); 20896fdf41d1SStefano Zampini if (bs > 0) { 2090d3ee2243SStefano Zampini ierr = MatSetBlockSize(*A,bs);CHKERRQ(ierr); 20916fdf41d1SStefano Zampini } 2092284134d9SBarry Smith ierr = MatSetSizes(*A,m,n,M,N);CHKERRQ(ierr); 2093284134d9SBarry Smith ierr = MatSetType(*A,MATIS);CHKERRQ(ierr); 2094e176bc59SStefano Zampini if (rmap && cmap) { 2095e176bc59SStefano Zampini ierr = MatSetLocalToGlobalMapping(*A,rmap,cmap);CHKERRQ(ierr); 2096e176bc59SStefano Zampini } else if (!rmap) { 2097e176bc59SStefano Zampini ierr = MatSetLocalToGlobalMapping(*A,cmap,cmap);CHKERRQ(ierr); 2098e176bc59SStefano Zampini } else { 2099e176bc59SStefano Zampini ierr = MatSetLocalToGlobalMapping(*A,rmap,rmap);CHKERRQ(ierr); 2100e176bc59SStefano Zampini } 2101284134d9SBarry Smith PetscFunctionReturn(0); 2102284134d9SBarry Smith } 2103284134d9SBarry Smith 2104b4319ba4SBarry Smith /*MC 2105f26d0771SStefano Zampini MATIS - MATIS = "is" - A matrix type to be used for using the non-overlapping domain decomposition methods (e.g. PCBDDC or KSPFETIDP). 2106b4319ba4SBarry Smith This stores the matrices in globally unassembled form. Each processor 2107b4319ba4SBarry Smith assembles only its local Neumann problem and the parallel matrix vector 2108b4319ba4SBarry Smith product is handled "implicitly". 2109b4319ba4SBarry Smith 2110b4319ba4SBarry Smith Operations Provided: 21116726f965SBarry Smith + MatMult() 21122e74eeadSLisandro Dalcin . MatMultAdd() 21132e74eeadSLisandro Dalcin . MatMultTranspose() 21142e74eeadSLisandro Dalcin . MatMultTransposeAdd() 21156726f965SBarry Smith . MatZeroEntries() 21166726f965SBarry Smith . MatSetOption() 21172e74eeadSLisandro Dalcin . MatZeroRows() 21182e74eeadSLisandro Dalcin . MatSetValues() 211997563a80SStefano Zampini . MatSetValuesBlocked() 21206726f965SBarry Smith . MatSetValuesLocal() 212197563a80SStefano Zampini . MatSetValuesBlockedLocal() 21222e74eeadSLisandro Dalcin . MatScale() 21232e74eeadSLisandro Dalcin . MatGetDiagonal() 21242b404112SStefano Zampini . MatMissingDiagonal() 21252b404112SStefano Zampini . MatDuplicate() 21262b404112SStefano Zampini . MatCopy() 2127f26d0771SStefano Zampini . MatAXPY() 2128f26d0771SStefano Zampini . MatGetSubMatrix() 2129f26d0771SStefano Zampini . MatGetLocalSubMatrix() 2130d7f69cd0SStefano Zampini . MatTranspose() 21316726f965SBarry Smith - MatSetLocalToGlobalMapping() 2132b4319ba4SBarry Smith 2133b4319ba4SBarry Smith Options Database Keys: 2134b4319ba4SBarry Smith . -mat_type is - sets the matrix type to "is" during a call to MatSetFromOptions() 2135b4319ba4SBarry Smith 2136b4319ba4SBarry Smith Notes: Options prefix for the inner matrix are given by -is_mat_xxx 2137b4319ba4SBarry Smith 2138b4319ba4SBarry Smith You must call MatSetLocalToGlobalMapping() before using this matrix type. 2139b4319ba4SBarry Smith 2140b4319ba4SBarry Smith You can do matrix preallocation on the local matrix after you obtain it with 2141eb82efa4SStefano Zampini MatISGetLocalMat(); otherwise, you could use MatISSetPreallocation() 2142b4319ba4SBarry Smith 2143b4319ba4SBarry Smith Level: advanced 2144b4319ba4SBarry Smith 2145f26d0771SStefano Zampini .seealso: Mat, MatISGetLocalMat(), MatSetLocalToGlobalMapping(), MatISSetPreallocation(), MatCreateIS(), PCBDDC, KSPFETIDP 2146b4319ba4SBarry Smith 2147b4319ba4SBarry Smith M*/ 2148b4319ba4SBarry Smith 2149b4319ba4SBarry Smith #undef __FUNCT__ 2150b4319ba4SBarry Smith #define __FUNCT__ "MatCreate_IS" 21518cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatCreate_IS(Mat A) 2152b4319ba4SBarry Smith { 2153dfbe8321SBarry Smith PetscErrorCode ierr; 2154b4319ba4SBarry Smith Mat_IS *b; 2155b4319ba4SBarry Smith 2156b4319ba4SBarry Smith PetscFunctionBegin; 2157b00a9115SJed Brown ierr = PetscNewLog(A,&b);CHKERRQ(ierr); 2158b4319ba4SBarry Smith A->data = (void*)b; 2159b4319ba4SBarry Smith 2160e176bc59SStefano Zampini /* matrix ops */ 2161e176bc59SStefano Zampini ierr = PetscMemzero(A->ops,sizeof(struct _MatOps));CHKERRQ(ierr); 2162b4319ba4SBarry Smith A->ops->mult = MatMult_IS; 21632e74eeadSLisandro Dalcin A->ops->multadd = MatMultAdd_IS; 21642e74eeadSLisandro Dalcin A->ops->multtranspose = MatMultTranspose_IS; 21652e74eeadSLisandro Dalcin A->ops->multtransposeadd = MatMultTransposeAdd_IS; 2166b4319ba4SBarry Smith A->ops->destroy = MatDestroy_IS; 2167b4319ba4SBarry Smith A->ops->setlocaltoglobalmapping = MatSetLocalToGlobalMapping_IS; 21682e74eeadSLisandro Dalcin A->ops->setvalues = MatSetValues_IS; 216998921651SStefano Zampini A->ops->setvaluesblocked = MatSetValuesBlocked_IS; 2170b4319ba4SBarry Smith A->ops->setvalueslocal = MatSetValuesLocal_IS; 2171f0006bf2SLisandro Dalcin A->ops->setvaluesblockedlocal = MatSetValuesBlockedLocal_IS; 21722e74eeadSLisandro Dalcin A->ops->zerorows = MatZeroRows_IS; 2173f0ae7da4SStefano Zampini A->ops->zerorowscolumns = MatZeroRowsColumns_IS; 2174b4319ba4SBarry Smith A->ops->assemblybegin = MatAssemblyBegin_IS; 2175b4319ba4SBarry Smith A->ops->assemblyend = MatAssemblyEnd_IS; 2176b4319ba4SBarry Smith A->ops->view = MatView_IS; 21776726f965SBarry Smith A->ops->zeroentries = MatZeroEntries_IS; 21782e74eeadSLisandro Dalcin A->ops->scale = MatScale_IS; 21792e74eeadSLisandro Dalcin A->ops->getdiagonal = MatGetDiagonal_IS; 21806726f965SBarry Smith A->ops->setoption = MatSetOption_IS; 218169796d55SStefano Zampini A->ops->ishermitian = MatIsHermitian_IS; 218269796d55SStefano Zampini A->ops->issymmetric = MatIsSymmetric_IS; 218345471136SStefano Zampini A->ops->isstructurallysymmetric = MatIsStructurallySymmetric_IS; 2184ad6194a2SStefano Zampini A->ops->duplicate = MatDuplicate_IS; 21856bd84002SStefano Zampini A->ops->missingdiagonal = MatMissingDiagonal_IS; 21862b404112SStefano Zampini A->ops->copy = MatCopy_IS; 2187659959c5SStefano Zampini A->ops->getlocalsubmatrix = MatGetLocalSubMatrix_IS; 2188a8116848SStefano Zampini A->ops->getsubmatrix = MatGetSubMatrix_IS; 2189f26d0771SStefano Zampini A->ops->axpy = MatAXPY_IS; 21903fd1c9e7SStefano Zampini A->ops->diagonalset = MatDiagonalSet_IS; 21913fd1c9e7SStefano Zampini A->ops->shift = MatShift_IS; 2192d7f69cd0SStefano Zampini A->ops->transpose = MatTranspose_IS; 2193b4319ba4SBarry Smith 2194b7ce53b6SStefano Zampini /* special MATIS functions */ 2195bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatISGetLocalMat_C",MatISGetLocalMat_IS);CHKERRQ(ierr); 2196bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatISSetLocalMat_C",MatISSetLocalMat_IS);CHKERRQ(ierr); 2197b7ce53b6SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatISGetMPIXAIJ_C",MatISGetMPIXAIJ_IS);CHKERRQ(ierr); 21982e1947a5SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatISSetPreallocation_C",MatISSetPreallocation_IS);CHKERRQ(ierr); 2199cf0a3239SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatISSetUpSF_C",MatISSetUpSF_IS);CHKERRQ(ierr); 220017667f90SBarry Smith ierr = PetscObjectChangeTypeName((PetscObject)A,MATIS);CHKERRQ(ierr); 2201b4319ba4SBarry Smith PetscFunctionReturn(0); 2202b4319ba4SBarry Smith } 2203