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__ 17*5b003df0Sstefano_zampini #define __FUNCT__ "MatISContainerDestroyFields_Private" 18*5b003df0Sstefano_zampini static PetscErrorCode MatISContainerDestroyFields_Private(void *ptr) 19*5b003df0Sstefano_zampini { 20*5b003df0Sstefano_zampini MatISLocalFields lf = (MatISLocalFields)ptr; 21*5b003df0Sstefano_zampini PetscInt i; 22*5b003df0Sstefano_zampini PetscErrorCode ierr; 23*5b003df0Sstefano_zampini 24*5b003df0Sstefano_zampini PetscFunctionBeginUser; 25*5b003df0Sstefano_zampini for (i=0;i<lf->nr;i++) { 26*5b003df0Sstefano_zampini ierr = ISDestroy(&lf->rf[i]);CHKERRQ(ierr); 27*5b003df0Sstefano_zampini } 28*5b003df0Sstefano_zampini for (i=0;i<lf->nc;i++) { 29*5b003df0Sstefano_zampini ierr = ISDestroy(&lf->cf[i]);CHKERRQ(ierr); 30*5b003df0Sstefano_zampini } 31*5b003df0Sstefano_zampini ierr = PetscFree2(lf->rf,lf->cf);CHKERRQ(ierr); 32*5b003df0Sstefano_zampini ierr = PetscFree(lf);CHKERRQ(ierr); 33*5b003df0Sstefano_zampini PetscFunctionReturn(0); 34*5b003df0Sstefano_zampini } 35*5b003df0Sstefano_zampini 36*5b003df0Sstefano_zampini #undef __FUNCT__ 37*5b003df0Sstefano_zampini #define __FUNCT__ "MatISContainerDestroyArray_Private" 38*5b003df0Sstefano_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); 135*5b003df0Sstefano_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; 185*5b003df0Sstefano_zampini PetscInt *lr,*lc,*l2gidxs; 186*5b003df0Sstefano_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); 208*5b003df0Sstefano_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) { 298*5b003df0Sstefano_zampini PetscInt stl; 299*5b003df0Sstefano_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); 303*5b003df0Sstefano_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 */ 309*5b003df0Sstefano_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); 328*5b003df0Sstefano_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 */ 334*5b003df0Sstefano_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 { 380*5b003df0Sstefano_zampini PetscInt stl; 381*5b003df0Sstefano_zampini for (i=0,stl=0;i<nr;i++) { 382*5b003df0Sstefano_zampini ierr = ISCreateStride(PETSC_COMM_SELF,lr[i],stl,1,&islrow[i]);CHKERRQ(ierr); 383*5b003df0Sstefano_zampini stl += lr[i]; 3845e3038f0Sstefano_zampini } 385*5b003df0Sstefano_zampini for (i=0,stl=0;i<nc;i++) { 386*5b003df0Sstefano_zampini ierr = ISCreateStride(PETSC_COMM_SELF,lc[i],stl,1,&islcol[i]);CHKERRQ(ierr); 387*5b003df0Sstefano_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 397*5b003df0Sstefano_zampini /* Create local matrix in MATNEST format */ 398*5b003df0Sstefano_zampini convert = PETSC_FALSE; 399*5b003df0Sstefano_zampini ierr = PetscOptionsGetBool(NULL,((PetscObject)A)->prefix,"-matis_convert_local_nest",&convert,NULL);CHKERRQ(ierr); 400*5b003df0Sstefano_zampini if (convert) { 401*5b003df0Sstefano_zampini Mat M; 402*5b003df0Sstefano_zampini MatISLocalFields lf; 403*5b003df0Sstefano_zampini PetscContainer c; 404*5b003df0Sstefano_zampini 405*5b003df0Sstefano_zampini ierr = MatISGetLocalMat(*newmat,&lA);CHKERRQ(ierr); 406*5b003df0Sstefano_zampini ierr = MatConvert(lA,MATAIJ,MAT_INITIAL_MATRIX,&M);CHKERRQ(ierr); 407*5b003df0Sstefano_zampini ierr = MatISSetLocalMat(*newmat,M);CHKERRQ(ierr); 408*5b003df0Sstefano_zampini ierr = MatDestroy(&M);CHKERRQ(ierr); 409*5b003df0Sstefano_zampini 410*5b003df0Sstefano_zampini /* attach local fields to the matrix */ 411*5b003df0Sstefano_zampini ierr = PetscNew(&lf);CHKERRQ(ierr); 412*5b003df0Sstefano_zampini ierr = PetscCalloc2(nr,&lf->rf,nc,&lf->cf);CHKERRQ(ierr); 413*5b003df0Sstefano_zampini for (i=0;i<nr;i++) { 414*5b003df0Sstefano_zampini PetscInt n,st; 415*5b003df0Sstefano_zampini 416*5b003df0Sstefano_zampini ierr = ISGetLocalSize(islrow[i],&n);CHKERRQ(ierr); 417*5b003df0Sstefano_zampini ierr = ISStrideGetInfo(islrow[i],&st,NULL);CHKERRQ(ierr); 418*5b003df0Sstefano_zampini ierr = ISCreateStride(comm,n,st,1,&lf->rf[i]);CHKERRQ(ierr); 419*5b003df0Sstefano_zampini } 420*5b003df0Sstefano_zampini for (i=0;i<nc;i++) { 421*5b003df0Sstefano_zampini PetscInt n,st; 422*5b003df0Sstefano_zampini 423*5b003df0Sstefano_zampini ierr = ISGetLocalSize(islcol[i],&n);CHKERRQ(ierr); 424*5b003df0Sstefano_zampini ierr = ISStrideGetInfo(islcol[i],&st,NULL);CHKERRQ(ierr); 425*5b003df0Sstefano_zampini ierr = ISCreateStride(comm,n,st,1,&lf->cf[i]);CHKERRQ(ierr); 426*5b003df0Sstefano_zampini } 427*5b003df0Sstefano_zampini lf->nr = nr; 428*5b003df0Sstefano_zampini lf->nc = nc; 429*5b003df0Sstefano_zampini ierr = PetscContainerCreate(PetscObjectComm((PetscObject)(*newmat)),&c);CHKERRQ(ierr); 430*5b003df0Sstefano_zampini ierr = PetscContainerSetPointer(c,lf);CHKERRQ(ierr); 431*5b003df0Sstefano_zampini ierr = PetscContainerSetUserDestroy(c,MatISContainerDestroyFields_Private);CHKERRQ(ierr); 432*5b003df0Sstefano_zampini ierr = PetscObjectCompose((PetscObject)(*newmat),"_convert_nest_lfields",(PetscObject)c);CHKERRQ(ierr); 433*5b003df0Sstefano_zampini ierr = PetscContainerDestroy(&c);CHKERRQ(ierr); 434*5b003df0Sstefano_zampini } 435*5b003df0Sstefano_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); 444*5b003df0Sstefano_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; 11321670daf9Sstefano_zampini const PetscInt *ridxs,*cidxs; 11331670daf9Sstefano_zampini 11341670daf9Sstefano_zampini ierr = ISLocalToGlobalMappingGetIndices(mat->rmap->mapping,&ridxs);CHKERRQ(ierr); 11351670daf9Sstefano_zampini ierr = ISLocalToGlobalMappingGetIndices(mat->cmap->mapping,&cidxs);CHKERRQ(ierr); 11361670daf9Sstefano_zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,mat->rmap->n,ridxs,PETSC_USE_POINTER,&rows);CHKERRQ(ierr); 11371670daf9Sstefano_zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,mat->cmap->n,cidxs,PETSC_USE_POINTER,&cols);CHKERRQ(ierr); 11381670daf9Sstefano_zampini ierr = MatConvert(matis->A,MATAIJ,MAT_INITIAL_MATRIX,&B);CHKERRQ(ierr); 11391670daf9Sstefano_zampini ierr = MatGetSubMatrix(B,rows,cols,reuse,M);CHKERRQ(ierr); 11401670daf9Sstefano_zampini ierr = MatDestroy(&B);CHKERRQ(ierr); 11411670daf9Sstefano_zampini ierr = ISDestroy(&cols);CHKERRQ(ierr); 11421670daf9Sstefano_zampini ierr = ISDestroy(&rows);CHKERRQ(ierr); 11431670daf9Sstefano_zampini ierr = ISLocalToGlobalMappingRestoreIndices(mat->rmap->mapping,&ridxs);CHKERRQ(ierr); 11441670daf9Sstefano_zampini ierr = ISLocalToGlobalMappingRestoreIndices(mat->cmap->mapping,&cidxs);CHKERRQ(ierr); 11457c03b4e8SStefano Zampini PetscFunctionReturn(0); 11467c03b4e8SStefano Zampini } 1147b7ce53b6SStefano Zampini ierr = MatGetSize(mat,&rows,&cols);CHKERRQ(ierr); 1148b7ce53b6SStefano Zampini ierr = MatGetBlockSize(mat,&bs);CHKERRQ(ierr); 11493cfa4ea4SStefano Zampini ierr = MatGetLocalSize(mat,&lrows,&lcols);CHKERRQ(ierr); 1150b7ce53b6SStefano Zampini ierr = MatGetSize(matis->A,&local_rows,&local_cols);CHKERRQ(ierr); 1151b9ed4604SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)matis->A,MATSEQDENSE,&isseqdense);CHKERRQ(ierr); 1152686e3a49SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)matis->A,MATSEQAIJ,&isseqaij);CHKERRQ(ierr); 1153b9ed4604SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)matis->A,MATSEQBAIJ,&isseqbaij);CHKERRQ(ierr); 1154b9ed4604SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)matis->A,MATSEQSBAIJ,&isseqsbaij);CHKERRQ(ierr); 1155b9ed4604SStefano Zampini if (!isseqdense && !isseqaij && !isseqbaij && !isseqsbaij) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not for matrix type %s",((PetscObject)(matis->A))->type_name); 1156b9ed4604SStefano Zampini #if defined (PETSC_USE_DEBUG) 1157b9ed4604SStefano Zampini lb[0] = isseqdense; 1158b9ed4604SStefano Zampini lb[1] = isseqaij; 1159b9ed4604SStefano Zampini lb[2] = isseqbaij; 1160b9ed4604SStefano Zampini lb[3] = isseqsbaij; 1161b9ed4604SStefano Zampini ierr = MPIU_Allreduce(lb,bb,4,MPIU_BOOL,MPI_LAND,PetscObjectComm((PetscObject)mat));CHKERRQ(ierr); 1162b9ed4604SStefano Zampini if (!bb[0] && !bb[1] && !bb[2] && !bb[3]) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Local matrices must have the same type"); 1163b9ed4604SStefano Zampini #endif 1164b7ce53b6SStefano Zampini 1165b7ce53b6SStefano Zampini if (reuse == MAT_INITIAL_MATRIX) { 11663927de2eSStefano Zampini ierr = MatCreate(PetscObjectComm((PetscObject)mat),M);CHKERRQ(ierr); 11673cfa4ea4SStefano Zampini ierr = MatSetSizes(*M,lrows,lcols,rows,cols);CHKERRQ(ierr); 11683927de2eSStefano Zampini ierr = MatSetBlockSize(*M,bs);CHKERRQ(ierr); 1169b9ed4604SStefano Zampini if (!isseqsbaij) { 1170b9ed4604SStefano Zampini ierr = MatSetType(*M,MATAIJ);CHKERRQ(ierr); 1171b9ed4604SStefano Zampini } else { 1172b9ed4604SStefano Zampini ierr = MatSetType(*M,MATSBAIJ);CHKERRQ(ierr); 1173b9ed4604SStefano Zampini } 11743927de2eSStefano Zampini ierr = MatISSetMPIXAIJPreallocation_Private(mat,*M,PETSC_FALSE);CHKERRQ(ierr); 1175b7ce53b6SStefano Zampini } else { 11763cfa4ea4SStefano Zampini PetscInt mbs,mrows,mcols,mlrows,mlcols; 1177b7ce53b6SStefano Zampini /* some checks */ 1178b7ce53b6SStefano Zampini ierr = MatGetBlockSize(*M,&mbs);CHKERRQ(ierr); 1179b7ce53b6SStefano Zampini ierr = MatGetSize(*M,&mrows,&mcols);CHKERRQ(ierr); 11803cfa4ea4SStefano Zampini ierr = MatGetLocalSize(*M,&mlrows,&mlcols);CHKERRQ(ierr); 11816c4ed002SBarry Smith if (mrows != rows) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot reuse matrix. Wrong number of rows (%d != %d)",rows,mrows); 11826c4ed002SBarry Smith if (mcols != cols) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot reuse matrix. Wrong number of cols (%d != %d)",cols,mcols); 11836c4ed002SBarry Smith if (mlrows != lrows) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot reuse matrix. Wrong number of local rows (%d != %d)",lrows,mlrows); 11846c4ed002SBarry Smith if (mlcols != lcols) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot reuse matrix. Wrong number of local cols (%d != %d)",lcols,mlcols); 11856c4ed002SBarry Smith if (mbs != bs) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot reuse matrix. Wrong block size (%d != %d)",bs,mbs); 1186b7ce53b6SStefano Zampini ierr = MatZeroEntries(*M);CHKERRQ(ierr); 1187b7ce53b6SStefano Zampini } 1188d9a9e74cSStefano Zampini 1189b9ed4604SStefano Zampini if (isseqsbaij) { 1190d9a9e74cSStefano Zampini ierr = MatConvert(matis->A,MATSEQBAIJ,MAT_INITIAL_MATRIX,&local_mat);CHKERRQ(ierr); 1191d9a9e74cSStefano Zampini } else { 1192d9a9e74cSStefano Zampini ierr = PetscObjectReference((PetscObject)matis->A);CHKERRQ(ierr); 1193d9a9e74cSStefano Zampini local_mat = matis->A; 1194d9a9e74cSStefano Zampini } 1195686e3a49SStefano Zampini 1196b7ce53b6SStefano Zampini /* Set values */ 1197ecf5a873SStefano Zampini ierr = MatSetLocalToGlobalMapping(*M,mat->rmap->mapping,mat->cmap->mapping);CHKERRQ(ierr); 1198b9ed4604SStefano Zampini if (isseqdense) { /* special case for dense local matrices */ 1199ecf5a873SStefano Zampini PetscInt i,*dummy_rows,*dummy_cols; 1200ecf5a873SStefano Zampini 1201ecf5a873SStefano Zampini if (local_rows != local_cols) { 1202ecf5a873SStefano Zampini ierr = PetscMalloc2(local_rows,&dummy_rows,local_cols,&dummy_cols);CHKERRQ(ierr); 1203ecf5a873SStefano Zampini for (i=0;i<local_rows;i++) dummy_rows[i] = i; 1204ecf5a873SStefano Zampini for (i=0;i<local_cols;i++) dummy_cols[i] = i; 1205ecf5a873SStefano Zampini } else { 1206ecf5a873SStefano Zampini ierr = PetscMalloc1(local_rows,&dummy_rows);CHKERRQ(ierr); 1207ecf5a873SStefano Zampini for (i=0;i<local_rows;i++) dummy_rows[i] = i; 1208ecf5a873SStefano Zampini dummy_cols = dummy_rows; 1209ecf5a873SStefano Zampini } 1210b7ce53b6SStefano Zampini ierr = MatSetOption(*M,MAT_ROW_ORIENTED,PETSC_FALSE);CHKERRQ(ierr); 1211d9a9e74cSStefano Zampini ierr = MatDenseGetArray(local_mat,&array);CHKERRQ(ierr); 1212ecf5a873SStefano Zampini ierr = MatSetValuesLocal(*M,local_rows,dummy_rows,local_cols,dummy_cols,array,ADD_VALUES);CHKERRQ(ierr); 1213d9a9e74cSStefano Zampini ierr = MatDenseRestoreArray(local_mat,&array);CHKERRQ(ierr); 1214ecf5a873SStefano Zampini if (dummy_rows != dummy_cols) { 1215ecf5a873SStefano Zampini ierr = PetscFree2(dummy_rows,dummy_cols);CHKERRQ(ierr); 1216ecf5a873SStefano Zampini } else { 1217ecf5a873SStefano Zampini ierr = PetscFree(dummy_rows);CHKERRQ(ierr); 1218ecf5a873SStefano Zampini } 1219686e3a49SStefano Zampini } else if (isseqaij) { 1220ecf5a873SStefano Zampini PetscInt i,nvtxs,*xadj,*adjncy; 1221686e3a49SStefano Zampini PetscBool done; 1222686e3a49SStefano Zampini 1223d9a9e74cSStefano Zampini ierr = MatGetRowIJ(local_mat,0,PETSC_FALSE,PETSC_FALSE,&nvtxs,(const PetscInt**)&xadj,(const PetscInt**)&adjncy,&done);CHKERRQ(ierr); 1224bb1015c3SStefano Zampini if (!done) SETERRQ1(PetscObjectComm((PetscObject)local_mat),PETSC_ERR_PLIB,"Error in MatGetRowIJ called from %s\n",__FUNCT__); 1225d9a9e74cSStefano Zampini ierr = MatSeqAIJGetArray(local_mat,&array);CHKERRQ(ierr); 1226686e3a49SStefano Zampini for (i=0;i<nvtxs;i++) { 1227ecf5a873SStefano Zampini ierr = MatSetValuesLocal(*M,1,&i,xadj[i+1]-xadj[i],adjncy+xadj[i],array+xadj[i],ADD_VALUES);CHKERRQ(ierr); 1228686e3a49SStefano Zampini } 1229d9a9e74cSStefano Zampini ierr = MatRestoreRowIJ(local_mat,0,PETSC_FALSE,PETSC_FALSE,&nvtxs,(const PetscInt**)&xadj,(const PetscInt**)&adjncy,&done);CHKERRQ(ierr); 1230bb1015c3SStefano Zampini if (!done) SETERRQ1(PetscObjectComm((PetscObject)local_mat),PETSC_ERR_PLIB,"Error in MatRestoreRowIJ called from %s\n",__FUNCT__); 1231d9a9e74cSStefano Zampini ierr = MatSeqAIJRestoreArray(local_mat,&array);CHKERRQ(ierr); 1232686e3a49SStefano Zampini } else { /* very basic values insertion for all other matrix types */ 1233ecf5a873SStefano Zampini PetscInt i; 1234c0962df8SStefano Zampini 1235686e3a49SStefano Zampini for (i=0;i<local_rows;i++) { 1236686e3a49SStefano Zampini PetscInt j; 1237ecf5a873SStefano Zampini const PetscInt *local_indices_cols; 1238686e3a49SStefano Zampini 1239ecf5a873SStefano Zampini ierr = MatGetRow(local_mat,i,&j,&local_indices_cols,(const PetscScalar**)&array);CHKERRQ(ierr); 1240ecf5a873SStefano Zampini ierr = MatSetValuesLocal(*M,1,&i,j,local_indices_cols,array,ADD_VALUES);CHKERRQ(ierr); 1241ecf5a873SStefano Zampini ierr = MatRestoreRow(local_mat,i,&j,&local_indices_cols,(const PetscScalar**)&array);CHKERRQ(ierr); 1242686e3a49SStefano Zampini } 1243b7ce53b6SStefano Zampini } 1244b7ce53b6SStefano Zampini ierr = MatAssemblyBegin(*M,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1245d9a9e74cSStefano Zampini ierr = MatDestroy(&local_mat);CHKERRQ(ierr); 1246b7ce53b6SStefano Zampini ierr = MatAssemblyEnd(*M,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1247b9ed4604SStefano Zampini if (isseqdense) { 1248b7ce53b6SStefano Zampini ierr = MatSetOption(*M,MAT_ROW_ORIENTED,PETSC_TRUE);CHKERRQ(ierr); 1249b7ce53b6SStefano Zampini } 1250b7ce53b6SStefano Zampini PetscFunctionReturn(0); 1251b7ce53b6SStefano Zampini } 1252b7ce53b6SStefano Zampini 1253b7ce53b6SStefano Zampini #undef __FUNCT__ 1254b7ce53b6SStefano Zampini #define __FUNCT__ "MatISGetMPIXAIJ" 1255b7ce53b6SStefano Zampini /*@ 1256b7ce53b6SStefano Zampini MatISGetMPIXAIJ - Converts MATIS matrix into a parallel AIJ format 1257b7ce53b6SStefano Zampini 1258b7ce53b6SStefano Zampini Input Parameter: 1259b7ce53b6SStefano Zampini . mat - the matrix (should be of type MATIS) 1260b7ce53b6SStefano Zampini . reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 1261b7ce53b6SStefano Zampini 1262b7ce53b6SStefano Zampini Output Parameter: 1263b7ce53b6SStefano Zampini . newmat - the matrix in AIJ format 1264b7ce53b6SStefano Zampini 1265b7ce53b6SStefano Zampini Level: developer 1266b7ce53b6SStefano Zampini 1267eb82efa4SStefano Zampini Notes: mat and *newmat cannot be the same object when MAT_REUSE_MATRIX is requested. 1268b7ce53b6SStefano Zampini 1269b7ce53b6SStefano Zampini .seealso: MATIS 1270b7ce53b6SStefano Zampini @*/ 1271b7ce53b6SStefano Zampini PetscErrorCode MatISGetMPIXAIJ(Mat mat, MatReuse reuse, Mat *newmat) 1272b7ce53b6SStefano Zampini { 1273b7ce53b6SStefano Zampini PetscErrorCode ierr; 1274b7ce53b6SStefano Zampini 1275b7ce53b6SStefano Zampini PetscFunctionBegin; 1276b7ce53b6SStefano Zampini PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1277b7ce53b6SStefano Zampini PetscValidLogicalCollectiveEnum(mat,reuse,2); 1278b7ce53b6SStefano Zampini PetscValidPointer(newmat,3); 1279b7ce53b6SStefano Zampini if (reuse != MAT_INITIAL_MATRIX) { 1280b7ce53b6SStefano Zampini PetscValidHeaderSpecific(*newmat,MAT_CLASSID,3); 1281b7ce53b6SStefano Zampini PetscCheckSameComm(mat,1,*newmat,3); 12826c4ed002SBarry Smith if (mat == *newmat) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot reuse the same matrix"); 1283b7ce53b6SStefano Zampini } 1284b7ce53b6SStefano Zampini ierr = PetscUseMethod(mat,"MatISGetMPIXAIJ_C",(Mat,MatReuse,Mat*),(mat,reuse,newmat));CHKERRQ(ierr); 1285b7ce53b6SStefano Zampini PetscFunctionReturn(0); 1286b7ce53b6SStefano Zampini } 1287b7ce53b6SStefano Zampini 1288b7ce53b6SStefano Zampini #undef __FUNCT__ 1289ad6194a2SStefano Zampini #define __FUNCT__ "MatDuplicate_IS" 1290ad6194a2SStefano Zampini PetscErrorCode MatDuplicate_IS(Mat mat,MatDuplicateOption op,Mat *newmat) 1291ad6194a2SStefano Zampini { 1292ad6194a2SStefano Zampini PetscErrorCode ierr; 1293ad6194a2SStefano Zampini Mat_IS *matis = (Mat_IS*)(mat->data); 1294ad6194a2SStefano Zampini PetscInt bs,m,n,M,N; 1295ad6194a2SStefano Zampini Mat B,localmat; 1296ad6194a2SStefano Zampini 1297ad6194a2SStefano Zampini PetscFunctionBegin; 1298ad6194a2SStefano Zampini ierr = MatGetBlockSize(mat,&bs);CHKERRQ(ierr); 1299ad6194a2SStefano Zampini ierr = MatGetSize(mat,&M,&N);CHKERRQ(ierr); 1300ad6194a2SStefano Zampini ierr = MatGetLocalSize(mat,&m,&n);CHKERRQ(ierr); 1301e176bc59SStefano Zampini ierr = MatCreateIS(PetscObjectComm((PetscObject)mat),bs,m,n,M,N,mat->rmap->mapping,mat->cmap->mapping,&B);CHKERRQ(ierr); 1302ad6194a2SStefano Zampini ierr = MatDuplicate(matis->A,op,&localmat);CHKERRQ(ierr); 1303ad6194a2SStefano Zampini ierr = MatISSetLocalMat(B,localmat);CHKERRQ(ierr); 1304b3317aa8SStefano Zampini ierr = MatDestroy(&localmat);CHKERRQ(ierr); 1305ad6194a2SStefano Zampini ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1306ad6194a2SStefano Zampini ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1307ad6194a2SStefano Zampini *newmat = B; 1308ad6194a2SStefano Zampini PetscFunctionReturn(0); 1309ad6194a2SStefano Zampini } 1310ad6194a2SStefano Zampini 1311ad6194a2SStefano Zampini #undef __FUNCT__ 131269796d55SStefano Zampini #define __FUNCT__ "MatIsHermitian_IS" 1313a8116848SStefano Zampini static PetscErrorCode MatIsHermitian_IS(Mat A,PetscReal tol,PetscBool *flg) 131469796d55SStefano Zampini { 131569796d55SStefano Zampini PetscErrorCode ierr; 131669796d55SStefano Zampini Mat_IS *matis = (Mat_IS*)A->data; 131769796d55SStefano Zampini PetscBool local_sym; 131869796d55SStefano Zampini 131969796d55SStefano Zampini PetscFunctionBegin; 132069796d55SStefano Zampini ierr = MatIsHermitian(matis->A,tol,&local_sym);CHKERRQ(ierr); 1321b2566f29SBarry Smith ierr = MPIU_Allreduce(&local_sym,flg,1,MPIU_BOOL,MPI_LAND,PetscObjectComm((PetscObject)A));CHKERRQ(ierr); 132269796d55SStefano Zampini PetscFunctionReturn(0); 132369796d55SStefano Zampini } 132469796d55SStefano Zampini 132569796d55SStefano Zampini #undef __FUNCT__ 132669796d55SStefano Zampini #define __FUNCT__ "MatIsSymmetric_IS" 1327a8116848SStefano Zampini static PetscErrorCode MatIsSymmetric_IS(Mat A,PetscReal tol,PetscBool *flg) 132869796d55SStefano Zampini { 132969796d55SStefano Zampini PetscErrorCode ierr; 133069796d55SStefano Zampini Mat_IS *matis = (Mat_IS*)A->data; 133169796d55SStefano Zampini PetscBool local_sym; 133269796d55SStefano Zampini 133369796d55SStefano Zampini PetscFunctionBegin; 133469796d55SStefano Zampini ierr = MatIsSymmetric(matis->A,tol,&local_sym);CHKERRQ(ierr); 1335b2566f29SBarry Smith ierr = MPIU_Allreduce(&local_sym,flg,1,MPIU_BOOL,MPI_LAND,PetscObjectComm((PetscObject)A));CHKERRQ(ierr); 133669796d55SStefano Zampini PetscFunctionReturn(0); 133769796d55SStefano Zampini } 133869796d55SStefano Zampini 133969796d55SStefano Zampini #undef __FUNCT__ 134045471136SStefano Zampini #define __FUNCT__ "MatIsStructurallySymmetric_IS" 134145471136SStefano Zampini static PetscErrorCode MatIsStructurallySymmetric_IS(Mat A,PetscBool *flg) 134245471136SStefano Zampini { 134345471136SStefano Zampini PetscErrorCode ierr; 134445471136SStefano Zampini Mat_IS *matis = (Mat_IS*)A->data; 134545471136SStefano Zampini PetscBool local_sym; 134645471136SStefano Zampini 134745471136SStefano Zampini PetscFunctionBegin; 134845471136SStefano Zampini if (A->rmap->mapping != A->cmap->mapping) { 134945471136SStefano Zampini *flg = PETSC_FALSE; 135045471136SStefano Zampini PetscFunctionReturn(0); 135145471136SStefano Zampini } 135245471136SStefano Zampini ierr = MatIsStructurallySymmetric(matis->A,&local_sym);CHKERRQ(ierr); 135345471136SStefano Zampini ierr = MPIU_Allreduce(&local_sym,flg,1,MPIU_BOOL,MPI_LAND,PetscObjectComm((PetscObject)A));CHKERRQ(ierr); 135445471136SStefano Zampini PetscFunctionReturn(0); 135545471136SStefano Zampini } 135645471136SStefano Zampini 135745471136SStefano Zampini #undef __FUNCT__ 1358b4319ba4SBarry Smith #define __FUNCT__ "MatDestroy_IS" 1359a8116848SStefano Zampini static PetscErrorCode MatDestroy_IS(Mat A) 1360b4319ba4SBarry Smith { 1361dfbe8321SBarry Smith PetscErrorCode ierr; 1362b4319ba4SBarry Smith Mat_IS *b = (Mat_IS*)A->data; 1363b4319ba4SBarry Smith 1364b4319ba4SBarry Smith PetscFunctionBegin; 13656bf464f9SBarry Smith ierr = MatDestroy(&b->A);CHKERRQ(ierr); 1366e176bc59SStefano Zampini ierr = VecScatterDestroy(&b->cctx);CHKERRQ(ierr); 1367e176bc59SStefano Zampini ierr = VecScatterDestroy(&b->rctx);CHKERRQ(ierr); 13686bf464f9SBarry Smith ierr = VecDestroy(&b->x);CHKERRQ(ierr); 13696bf464f9SBarry Smith ierr = VecDestroy(&b->y);CHKERRQ(ierr); 13703fd1c9e7SStefano Zampini ierr = VecDestroy(&b->counter);CHKERRQ(ierr); 1371a8116848SStefano Zampini ierr = ISDestroy(&b->getsub_ris);CHKERRQ(ierr); 1372a8116848SStefano Zampini ierr = ISDestroy(&b->getsub_cis);CHKERRQ(ierr); 1373a8116848SStefano Zampini if (b->sf != b->csf) { 1374a8116848SStefano Zampini ierr = PetscSFDestroy(&b->csf);CHKERRQ(ierr); 1375a8116848SStefano Zampini ierr = PetscFree2(b->csf_rootdata,b->csf_leafdata);CHKERRQ(ierr); 1376a8116848SStefano Zampini } 137728f4e0baSStefano Zampini ierr = PetscSFDestroy(&b->sf);CHKERRQ(ierr); 137828f4e0baSStefano Zampini ierr = PetscFree2(b->sf_rootdata,b->sf_leafdata);CHKERRQ(ierr); 1379bf0cc555SLisandro Dalcin ierr = PetscFree(A->data);CHKERRQ(ierr); 1380dbd8c25aSHong Zhang ierr = PetscObjectChangeTypeName((PetscObject)A,0);CHKERRQ(ierr); 1381bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatISGetLocalMat_C",NULL);CHKERRQ(ierr); 1382b7ce53b6SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatISSetLocalMat_C",NULL);CHKERRQ(ierr); 1383b7ce53b6SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatISGetMPIXAIJ_C",NULL);CHKERRQ(ierr); 13842e1947a5SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatISSetPreallocation_C",NULL);CHKERRQ(ierr); 1385cf0a3239SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatISSetUpSF_C",NULL);CHKERRQ(ierr); 1386b4319ba4SBarry Smith PetscFunctionReturn(0); 1387b4319ba4SBarry Smith } 1388b4319ba4SBarry Smith 1389b4319ba4SBarry Smith #undef __FUNCT__ 1390b4319ba4SBarry Smith #define __FUNCT__ "MatMult_IS" 1391a8116848SStefano Zampini static PetscErrorCode MatMult_IS(Mat A,Vec x,Vec y) 1392b4319ba4SBarry Smith { 1393dfbe8321SBarry Smith PetscErrorCode ierr; 1394b4319ba4SBarry Smith Mat_IS *is = (Mat_IS*)A->data; 1395b4319ba4SBarry Smith PetscScalar zero = 0.0; 1396b4319ba4SBarry Smith 1397b4319ba4SBarry Smith PetscFunctionBegin; 1398b4319ba4SBarry Smith /* scatter the global vector x into the local work vector */ 1399e176bc59SStefano Zampini ierr = VecScatterBegin(is->cctx,x,is->x,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1400e176bc59SStefano Zampini ierr = VecScatterEnd(is->cctx,x,is->x,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1401b4319ba4SBarry Smith 1402b4319ba4SBarry Smith /* multiply the local matrix */ 1403b4319ba4SBarry Smith ierr = MatMult(is->A,is->x,is->y);CHKERRQ(ierr); 1404b4319ba4SBarry Smith 1405b4319ba4SBarry Smith /* scatter product back into global memory */ 14062dcb1b2aSMatthew Knepley ierr = VecSet(y,zero);CHKERRQ(ierr); 1407e176bc59SStefano Zampini ierr = VecScatterBegin(is->rctx,is->y,y,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 1408e176bc59SStefano Zampini ierr = VecScatterEnd(is->rctx,is->y,y,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 1409b4319ba4SBarry Smith PetscFunctionReturn(0); 1410b4319ba4SBarry Smith } 1411b4319ba4SBarry Smith 1412b4319ba4SBarry Smith #undef __FUNCT__ 14132e74eeadSLisandro Dalcin #define __FUNCT__ "MatMultAdd_IS" 1414a8116848SStefano Zampini static PetscErrorCode MatMultAdd_IS(Mat A,Vec v1,Vec v2,Vec v3) 14152e74eeadSLisandro Dalcin { 1416650997f4SStefano Zampini Vec temp_vec; 14172e74eeadSLisandro Dalcin PetscErrorCode ierr; 14182e74eeadSLisandro Dalcin 14192e74eeadSLisandro Dalcin PetscFunctionBegin; /* v3 = v2 + A * v1.*/ 1420650997f4SStefano Zampini if (v3 != v2) { 1421650997f4SStefano Zampini ierr = MatMult(A,v1,v3);CHKERRQ(ierr); 1422650997f4SStefano Zampini ierr = VecAXPY(v3,1.0,v2);CHKERRQ(ierr); 1423650997f4SStefano Zampini } else { 1424650997f4SStefano Zampini ierr = VecDuplicate(v2,&temp_vec);CHKERRQ(ierr); 1425650997f4SStefano Zampini ierr = MatMult(A,v1,temp_vec);CHKERRQ(ierr); 1426650997f4SStefano Zampini ierr = VecAXPY(temp_vec,1.0,v2);CHKERRQ(ierr); 1427650997f4SStefano Zampini ierr = VecCopy(temp_vec,v3);CHKERRQ(ierr); 1428650997f4SStefano Zampini ierr = VecDestroy(&temp_vec);CHKERRQ(ierr); 1429650997f4SStefano Zampini } 14302e74eeadSLisandro Dalcin PetscFunctionReturn(0); 14312e74eeadSLisandro Dalcin } 14322e74eeadSLisandro Dalcin 14332e74eeadSLisandro Dalcin #undef __FUNCT__ 14342e74eeadSLisandro Dalcin #define __FUNCT__ "MatMultTranspose_IS" 1435a8116848SStefano Zampini static PetscErrorCode MatMultTranspose_IS(Mat A,Vec y,Vec x) 14362e74eeadSLisandro Dalcin { 14372e74eeadSLisandro Dalcin Mat_IS *is = (Mat_IS*)A->data; 14382e74eeadSLisandro Dalcin PetscErrorCode ierr; 14392e74eeadSLisandro Dalcin 1440e176bc59SStefano Zampini PetscFunctionBegin; 14412e74eeadSLisandro Dalcin /* scatter the global vector x into the local work vector */ 1442e176bc59SStefano Zampini ierr = VecScatterBegin(is->rctx,y,is->y,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1443e176bc59SStefano Zampini ierr = VecScatterEnd(is->rctx,y,is->y,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 14442e74eeadSLisandro Dalcin 14452e74eeadSLisandro Dalcin /* multiply the local matrix */ 1446e176bc59SStefano Zampini ierr = MatMultTranspose(is->A,is->y,is->x);CHKERRQ(ierr); 14472e74eeadSLisandro Dalcin 14482e74eeadSLisandro Dalcin /* scatter product back into global vector */ 1449e176bc59SStefano Zampini ierr = VecSet(x,0);CHKERRQ(ierr); 1450e176bc59SStefano Zampini ierr = VecScatterBegin(is->cctx,is->x,x,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 1451e176bc59SStefano Zampini ierr = VecScatterEnd(is->cctx,is->x,x,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 14522e74eeadSLisandro Dalcin PetscFunctionReturn(0); 14532e74eeadSLisandro Dalcin } 14542e74eeadSLisandro Dalcin 14552e74eeadSLisandro Dalcin #undef __FUNCT__ 14562e74eeadSLisandro Dalcin #define __FUNCT__ "MatMultTransposeAdd_IS" 1457a8116848SStefano Zampini static PetscErrorCode MatMultTransposeAdd_IS(Mat A,Vec v1,Vec v2,Vec v3) 14582e74eeadSLisandro Dalcin { 1459650997f4SStefano Zampini Vec temp_vec; 14602e74eeadSLisandro Dalcin PetscErrorCode ierr; 14612e74eeadSLisandro Dalcin 14622e74eeadSLisandro Dalcin PetscFunctionBegin; /* v3 = v2 + A' * v1.*/ 1463650997f4SStefano Zampini if (v3 != v2) { 1464650997f4SStefano Zampini ierr = MatMultTranspose(A,v1,v3);CHKERRQ(ierr); 1465650997f4SStefano Zampini ierr = VecAXPY(v3,1.0,v2);CHKERRQ(ierr); 1466650997f4SStefano Zampini } else { 1467650997f4SStefano Zampini ierr = VecDuplicate(v2,&temp_vec);CHKERRQ(ierr); 1468650997f4SStefano Zampini ierr = MatMultTranspose(A,v1,temp_vec);CHKERRQ(ierr); 1469650997f4SStefano Zampini ierr = VecAXPY(temp_vec,1.0,v2);CHKERRQ(ierr); 1470650997f4SStefano Zampini ierr = VecCopy(temp_vec,v3);CHKERRQ(ierr); 1471650997f4SStefano Zampini ierr = VecDestroy(&temp_vec);CHKERRQ(ierr); 1472650997f4SStefano Zampini } 14732e74eeadSLisandro Dalcin PetscFunctionReturn(0); 14742e74eeadSLisandro Dalcin } 14752e74eeadSLisandro Dalcin 14762e74eeadSLisandro Dalcin #undef __FUNCT__ 1477b4319ba4SBarry Smith #define __FUNCT__ "MatView_IS" 1478a8116848SStefano Zampini static PetscErrorCode MatView_IS(Mat A,PetscViewer viewer) 1479b4319ba4SBarry Smith { 1480b4319ba4SBarry Smith Mat_IS *a = (Mat_IS*)A->data; 1481dfbe8321SBarry Smith PetscErrorCode ierr; 1482b4319ba4SBarry Smith PetscViewer sviewer; 1483ee2491ecSStefano Zampini PetscBool isascii,view = PETSC_TRUE; 1484b4319ba4SBarry Smith 1485b4319ba4SBarry Smith PetscFunctionBegin; 1486ee2491ecSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isascii);CHKERRQ(ierr); 1487ee2491ecSStefano Zampini if (isascii) { 1488ee2491ecSStefano Zampini PetscViewerFormat format; 1489ee2491ecSStefano Zampini 1490ee2491ecSStefano Zampini ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr); 1491ee2491ecSStefano Zampini if (format == PETSC_VIEWER_ASCII_INFO) view = PETSC_FALSE; 1492ee2491ecSStefano Zampini } 1493ee2491ecSStefano Zampini if (!view) PetscFunctionReturn(0); 14943f08860eSBarry Smith ierr = PetscViewerGetSubViewer(viewer,PETSC_COMM_SELF,&sviewer);CHKERRQ(ierr); 1495b4319ba4SBarry Smith ierr = MatView(a->A,sviewer);CHKERRQ(ierr); 14963f08860eSBarry Smith ierr = PetscViewerRestoreSubViewer(viewer,PETSC_COMM_SELF,&sviewer);CHKERRQ(ierr); 14976e520ac8SStefano Zampini ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 1498b4319ba4SBarry Smith PetscFunctionReturn(0); 1499b4319ba4SBarry Smith } 1500b4319ba4SBarry Smith 1501b4319ba4SBarry Smith #undef __FUNCT__ 1502b4319ba4SBarry Smith #define __FUNCT__ "MatSetLocalToGlobalMapping_IS" 1503a8116848SStefano Zampini static PetscErrorCode MatSetLocalToGlobalMapping_IS(Mat A,ISLocalToGlobalMapping rmapping,ISLocalToGlobalMapping cmapping) 1504b4319ba4SBarry Smith { 1505dfbe8321SBarry Smith PetscErrorCode ierr; 1506e176bc59SStefano Zampini PetscInt nr,rbs,nc,cbs; 1507b4319ba4SBarry Smith Mat_IS *is = (Mat_IS*)A->data; 1508b4319ba4SBarry Smith IS from,to; 1509e176bc59SStefano Zampini Vec cglobal,rglobal; 1510b4319ba4SBarry Smith 1511b4319ba4SBarry Smith PetscFunctionBegin; 1512784ac674SJed Brown PetscCheckSameComm(A,1,rmapping,2); 1513e176bc59SStefano Zampini PetscCheckSameComm(A,1,cmapping,3); 15143bbff08aSStefano Zampini /* Destroy any previous data */ 151570cf5478SStefano Zampini ierr = VecDestroy(&is->x);CHKERRQ(ierr); 151670cf5478SStefano Zampini ierr = VecDestroy(&is->y);CHKERRQ(ierr); 15173fd1c9e7SStefano Zampini ierr = VecDestroy(&is->counter);CHKERRQ(ierr); 1518e176bc59SStefano Zampini ierr = VecScatterDestroy(&is->rctx);CHKERRQ(ierr); 1519e176bc59SStefano Zampini ierr = VecScatterDestroy(&is->cctx);CHKERRQ(ierr); 15201c47cb0fSStefano Zampini ierr = MatDestroy(&is->A);CHKERRQ(ierr); 152128f4e0baSStefano Zampini ierr = PetscSFDestroy(&is->sf);CHKERRQ(ierr); 152228f4e0baSStefano Zampini ierr = PetscFree2(is->sf_rootdata,is->sf_leafdata);CHKERRQ(ierr); 15233bbff08aSStefano Zampini 15243bbff08aSStefano Zampini /* Setup Layout and set local to global maps */ 1525fc27028aSStefano Zampini ierr = PetscLayoutSetUp(A->rmap);CHKERRQ(ierr); 1526fc27028aSStefano Zampini ierr = PetscLayoutSetUp(A->cmap);CHKERRQ(ierr); 1527fa7f1dd8SStefano Zampini ierr = PetscLayoutSetISLocalToGlobalMapping(A->rmap,rmapping);CHKERRQ(ierr); 1528fa7f1dd8SStefano Zampini ierr = PetscLayoutSetISLocalToGlobalMapping(A->cmap,cmapping);CHKERRQ(ierr); 1529b4319ba4SBarry Smith 1530b4319ba4SBarry Smith /* Create the local matrix A */ 1531e176bc59SStefano Zampini ierr = ISLocalToGlobalMappingGetSize(rmapping,&nr);CHKERRQ(ierr); 1532e176bc59SStefano Zampini ierr = ISLocalToGlobalMappingGetBlockSize(rmapping,&rbs);CHKERRQ(ierr); 1533e176bc59SStefano Zampini ierr = ISLocalToGlobalMappingGetSize(cmapping,&nc);CHKERRQ(ierr); 1534e176bc59SStefano Zampini ierr = ISLocalToGlobalMappingGetBlockSize(cmapping,&cbs);CHKERRQ(ierr); 1535f69a0ea3SMatthew Knepley ierr = MatCreate(PETSC_COMM_SELF,&is->A);CHKERRQ(ierr); 1536e176bc59SStefano Zampini ierr = MatSetType(is->A,MATAIJ);CHKERRQ(ierr); 1537e176bc59SStefano Zampini ierr = MatSetSizes(is->A,nr,nc,nr,nc);CHKERRQ(ierr); 1538e176bc59SStefano Zampini ierr = MatSetBlockSizes(is->A,rbs,cbs);CHKERRQ(ierr); 1539ff130e51SJed Brown ierr = MatSetOptionsPrefix(is->A,((PetscObject)A)->prefix);CHKERRQ(ierr); 1540ff130e51SJed Brown ierr = MatAppendOptionsPrefix(is->A,"is_");CHKERRQ(ierr); 1541b4319ba4SBarry Smith ierr = MatSetFromOptions(is->A);CHKERRQ(ierr); 1542b4319ba4SBarry Smith 1543f26d0771SStefano Zampini if (!is->islocalref) { /* setup scatters and local vectors for MatMult */ 1544b4319ba4SBarry Smith /* Create the local work vectors */ 15453bbff08aSStefano Zampini ierr = MatCreateVecs(is->A,&is->x,&is->y);CHKERRQ(ierr); 1546b4319ba4SBarry Smith 1547e176bc59SStefano Zampini /* setup the global to local scatters */ 1548e176bc59SStefano Zampini ierr = MatCreateVecs(A,&cglobal,&rglobal);CHKERRQ(ierr); 1549e176bc59SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,nr,0,1,&to);CHKERRQ(ierr); 1550784ac674SJed Brown ierr = ISLocalToGlobalMappingApplyIS(rmapping,to,&from);CHKERRQ(ierr); 1551e176bc59SStefano Zampini ierr = VecScatterCreate(rglobal,from,is->y,to,&is->rctx);CHKERRQ(ierr); 1552e176bc59SStefano Zampini if (rmapping != cmapping) { 1553e176bc59SStefano Zampini ierr = ISDestroy(&to);CHKERRQ(ierr); 1554e176bc59SStefano Zampini ierr = ISDestroy(&from);CHKERRQ(ierr); 1555e176bc59SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,nc,0,1,&to);CHKERRQ(ierr); 1556e176bc59SStefano Zampini ierr = ISLocalToGlobalMappingApplyIS(cmapping,to,&from);CHKERRQ(ierr); 1557e176bc59SStefano Zampini ierr = VecScatterCreate(cglobal,from,is->x,to,&is->cctx);CHKERRQ(ierr); 1558e176bc59SStefano Zampini } else { 1559e176bc59SStefano Zampini ierr = PetscObjectReference((PetscObject)is->rctx);CHKERRQ(ierr); 1560e176bc59SStefano Zampini is->cctx = is->rctx; 1561e176bc59SStefano Zampini } 15623fd1c9e7SStefano Zampini 15633fd1c9e7SStefano Zampini /* interface counter vector (local) */ 15643fd1c9e7SStefano Zampini ierr = VecDuplicate(is->y,&is->counter);CHKERRQ(ierr); 15653fd1c9e7SStefano Zampini ierr = VecSet(is->y,1.);CHKERRQ(ierr); 15663fd1c9e7SStefano Zampini ierr = VecScatterBegin(is->rctx,is->y,rglobal,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 15673fd1c9e7SStefano Zampini ierr = VecScatterEnd(is->rctx,is->y,rglobal,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 15683fd1c9e7SStefano Zampini ierr = VecScatterBegin(is->rctx,rglobal,is->counter,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 15693fd1c9e7SStefano Zampini ierr = VecScatterEnd(is->rctx,rglobal,is->counter,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 15703fd1c9e7SStefano Zampini 15713fd1c9e7SStefano Zampini /* free workspace */ 1572e176bc59SStefano Zampini ierr = VecDestroy(&rglobal);CHKERRQ(ierr); 1573e176bc59SStefano Zampini ierr = VecDestroy(&cglobal);CHKERRQ(ierr); 15746bf464f9SBarry Smith ierr = ISDestroy(&to);CHKERRQ(ierr); 15756bf464f9SBarry Smith ierr = ISDestroy(&from);CHKERRQ(ierr); 1576f26d0771SStefano Zampini } 15779c0b00dbSStefano Zampini ierr = MatSetUp(A);CHKERRQ(ierr); 1578b4319ba4SBarry Smith PetscFunctionReturn(0); 1579b4319ba4SBarry Smith } 1580b4319ba4SBarry Smith 15812e74eeadSLisandro Dalcin #undef __FUNCT__ 15822e74eeadSLisandro Dalcin #define __FUNCT__ "MatSetValues_IS" 1583a8116848SStefano Zampini static PetscErrorCode MatSetValues_IS(Mat mat, PetscInt m,const PetscInt *rows, PetscInt n,const PetscInt *cols, const PetscScalar *values, InsertMode addv) 15842e74eeadSLisandro Dalcin { 15852e74eeadSLisandro Dalcin Mat_IS *is = (Mat_IS*)mat->data; 15862e74eeadSLisandro Dalcin PetscErrorCode ierr; 158797563a80SStefano Zampini #if defined(PETSC_USE_DEBUG) 158897563a80SStefano Zampini PetscInt i,zm,zn; 158997563a80SStefano Zampini #endif 1590f26d0771SStefano Zampini PetscInt rows_l[MATIS_MAX_ENTRIES_INSERTION],cols_l[MATIS_MAX_ENTRIES_INSERTION]; 15912e74eeadSLisandro Dalcin 15922e74eeadSLisandro Dalcin PetscFunctionBegin; 15932e74eeadSLisandro Dalcin #if defined(PETSC_USE_DEBUG) 1594f26d0771SStefano 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); 159597563a80SStefano Zampini /* count negative indices */ 159697563a80SStefano Zampini for (i=0,zm=0;i<m;i++) if (rows[i] < 0) zm++; 159797563a80SStefano Zampini for (i=0,zn=0;i<n;i++) if (cols[i] < 0) zn++; 15982e74eeadSLisandro Dalcin #endif 159997563a80SStefano Zampini ierr = ISGlobalToLocalMappingApply(mat->rmap->mapping,IS_GTOLM_MASK,m,rows,&m,rows_l);CHKERRQ(ierr); 160097563a80SStefano Zampini ierr = ISGlobalToLocalMappingApply(mat->cmap->mapping,IS_GTOLM_MASK,n,cols,&n,cols_l);CHKERRQ(ierr); 160197563a80SStefano Zampini #if defined(PETSC_USE_DEBUG) 160297563a80SStefano Zampini /* count negative indices (should be the same as before) */ 160397563a80SStefano Zampini for (i=0;i<m;i++) if (rows_l[i] < 0) zm--; 160497563a80SStefano Zampini for (i=0;i<n;i++) if (cols_l[i] < 0) zn--; 160597563a80SStefano 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"); 160697563a80SStefano 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"); 160797563a80SStefano Zampini #endif 16082e74eeadSLisandro Dalcin ierr = MatSetValues(is->A,m,rows_l,n,cols_l,values,addv);CHKERRQ(ierr); 16092e74eeadSLisandro Dalcin PetscFunctionReturn(0); 16102e74eeadSLisandro Dalcin } 16112e74eeadSLisandro Dalcin 1612b4319ba4SBarry Smith #undef __FUNCT__ 161397563a80SStefano Zampini #define __FUNCT__ "MatSetValuesBlocked_IS" 1614a8116848SStefano Zampini static PetscErrorCode MatSetValuesBlocked_IS(Mat mat, PetscInt m,const PetscInt *rows, PetscInt n,const PetscInt *cols, const PetscScalar *values, InsertMode addv) 161597563a80SStefano Zampini { 161697563a80SStefano Zampini Mat_IS *is = (Mat_IS*)mat->data; 161797563a80SStefano Zampini PetscErrorCode ierr; 161897563a80SStefano Zampini #if defined(PETSC_USE_DEBUG) 161997563a80SStefano Zampini PetscInt i,zm,zn; 162097563a80SStefano Zampini #endif 1621f26d0771SStefano Zampini PetscInt rows_l[MATIS_MAX_ENTRIES_INSERTION],cols_l[MATIS_MAX_ENTRIES_INSERTION]; 162297563a80SStefano Zampini 162397563a80SStefano Zampini PetscFunctionBegin; 162497563a80SStefano Zampini #if defined(PETSC_USE_DEBUG) 1625f26d0771SStefano 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); 162697563a80SStefano Zampini /* count negative indices */ 162797563a80SStefano Zampini for (i=0,zm=0;i<m;i++) if (rows[i] < 0) zm++; 162897563a80SStefano Zampini for (i=0,zn=0;i<n;i++) if (cols[i] < 0) zn++; 162997563a80SStefano Zampini #endif 163097563a80SStefano Zampini ierr = ISGlobalToLocalMappingApplyBlock(mat->rmap->mapping,IS_GTOLM_MASK,m,rows,&m,rows_l);CHKERRQ(ierr); 163197563a80SStefano Zampini ierr = ISGlobalToLocalMappingApplyBlock(mat->cmap->mapping,IS_GTOLM_MASK,n,cols,&n,cols_l);CHKERRQ(ierr); 163297563a80SStefano Zampini #if defined(PETSC_USE_DEBUG) 163397563a80SStefano Zampini /* count negative indices (should be the same as before) */ 163497563a80SStefano Zampini for (i=0;i<m;i++) if (rows_l[i] < 0) zm--; 163597563a80SStefano Zampini for (i=0;i<n;i++) if (cols_l[i] < 0) zn--; 163697563a80SStefano 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"); 163797563a80SStefano 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"); 163897563a80SStefano Zampini #endif 163997563a80SStefano Zampini ierr = MatSetValuesBlocked(is->A,m,rows_l,n,cols_l,values,addv);CHKERRQ(ierr); 164097563a80SStefano Zampini PetscFunctionReturn(0); 164197563a80SStefano Zampini } 164297563a80SStefano Zampini 164397563a80SStefano Zampini #undef __FUNCT__ 1644b4319ba4SBarry Smith #define __FUNCT__ "MatSetValuesLocal_IS" 1645a8116848SStefano Zampini static PetscErrorCode MatSetValuesLocal_IS(Mat A,PetscInt m,const PetscInt *rows, PetscInt n,const PetscInt *cols,const PetscScalar *values,InsertMode addv) 1646b4319ba4SBarry Smith { 1647dfbe8321SBarry Smith PetscErrorCode ierr; 1648b4319ba4SBarry Smith Mat_IS *is = (Mat_IS*)A->data; 1649b4319ba4SBarry Smith 1650b4319ba4SBarry Smith PetscFunctionBegin; 1651b4319ba4SBarry Smith ierr = MatSetValues(is->A,m,rows,n,cols,values,addv);CHKERRQ(ierr); 1652b4319ba4SBarry Smith PetscFunctionReturn(0); 1653b4319ba4SBarry Smith } 1654b4319ba4SBarry Smith 1655b4319ba4SBarry Smith #undef __FUNCT__ 1656f0006bf2SLisandro Dalcin #define __FUNCT__ "MatSetValuesBlockedLocal_IS" 1657a8116848SStefano Zampini static PetscErrorCode MatSetValuesBlockedLocal_IS(Mat A,PetscInt m,const PetscInt *rows, PetscInt n,const PetscInt *cols,const PetscScalar *values,InsertMode addv) 1658f0006bf2SLisandro Dalcin { 1659f0006bf2SLisandro Dalcin PetscErrorCode ierr; 1660f0006bf2SLisandro Dalcin Mat_IS *is = (Mat_IS*)A->data; 1661f0006bf2SLisandro Dalcin 1662f0006bf2SLisandro Dalcin PetscFunctionBegin; 1663f0006bf2SLisandro Dalcin ierr = MatSetValuesBlocked(is->A,m,rows,n,cols,values,addv);CHKERRQ(ierr); 1664f0006bf2SLisandro Dalcin PetscFunctionReturn(0); 1665f0006bf2SLisandro Dalcin } 1666f0006bf2SLisandro Dalcin 1667f0006bf2SLisandro Dalcin #undef __FUNCT__ 1668f0ae7da4SStefano Zampini #define __FUNCT__ "MatISZeroRowsColumnsLocal_Private" 1669f0ae7da4SStefano Zampini static PetscErrorCode MatISZeroRowsColumnsLocal_Private(Mat A,PetscInt n,const PetscInt rows[],PetscScalar diag,PetscBool columns) 16702e74eeadSLisandro Dalcin { 1671f0ae7da4SStefano Zampini Mat_IS *is = (Mat_IS*)A->data; 16722e74eeadSLisandro Dalcin PetscErrorCode ierr; 16732e74eeadSLisandro Dalcin 16742e74eeadSLisandro Dalcin PetscFunctionBegin; 1675f0ae7da4SStefano Zampini if (!n) { 1676f0ae7da4SStefano Zampini is->pure_neumann = PETSC_TRUE; 1677f0ae7da4SStefano Zampini } else { 1678f0ae7da4SStefano Zampini PetscInt i; 1679f0ae7da4SStefano Zampini is->pure_neumann = PETSC_FALSE; 1680f0ae7da4SStefano Zampini 1681f0ae7da4SStefano Zampini if (columns) { 1682f0ae7da4SStefano Zampini ierr = MatZeroRowsColumns(is->A,n,rows,diag,0,0);CHKERRQ(ierr); 1683f0ae7da4SStefano Zampini } else { 1684f0ae7da4SStefano Zampini ierr = MatZeroRows(is->A,n,rows,diag,0,0);CHKERRQ(ierr); 16852e74eeadSLisandro Dalcin } 1686f0ae7da4SStefano Zampini if (diag != 0.) { 1687f0ae7da4SStefano Zampini const PetscScalar *array; 1688f0ae7da4SStefano Zampini ierr = VecGetArrayRead(is->counter,&array);CHKERRQ(ierr); 1689f0ae7da4SStefano Zampini for (i=0; i<n; i++) { 1690f0ae7da4SStefano Zampini ierr = MatSetValue(is->A,rows[i],rows[i],diag/(array[rows[i]]),INSERT_VALUES);CHKERRQ(ierr); 1691f0ae7da4SStefano Zampini } 1692f0ae7da4SStefano Zampini ierr = VecRestoreArrayRead(is->counter,&array);CHKERRQ(ierr); 1693f0ae7da4SStefano Zampini } 1694f0ae7da4SStefano Zampini ierr = MatAssemblyBegin(is->A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1695f0ae7da4SStefano Zampini ierr = MatAssemblyEnd(is->A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1696f0ae7da4SStefano Zampini } 16972e74eeadSLisandro Dalcin PetscFunctionReturn(0); 16982e74eeadSLisandro Dalcin } 16992e74eeadSLisandro Dalcin 17002e74eeadSLisandro Dalcin #undef __FUNCT__ 1701f0ae7da4SStefano Zampini #define __FUNCT__ "MatZeroRowsColumns_Private_IS" 1702f0ae7da4SStefano Zampini static PetscErrorCode MatZeroRowsColumns_Private_IS(Mat A,PetscInt n,const PetscInt rows[],PetscScalar diag,Vec x,Vec b,PetscBool columns) 1703b4319ba4SBarry Smith { 17046e520ac8SStefano Zampini Mat_IS *matis = (Mat_IS*)A->data; 17056e520ac8SStefano Zampini PetscInt nr,nl,len,i; 17066e520ac8SStefano Zampini PetscInt *lrows; 1707dfbe8321SBarry Smith PetscErrorCode ierr; 1708b4319ba4SBarry Smith 1709b4319ba4SBarry Smith PetscFunctionBegin; 1710f0ae7da4SStefano Zampini #if defined(PETSC_USE_DEBUG) 1711f0ae7da4SStefano Zampini if (columns || diag != 0. || (x && b)) { 1712f0ae7da4SStefano Zampini PetscBool cong; 1713f0ae7da4SStefano Zampini ierr = PetscLayoutCompare(A->rmap,A->cmap,&cong);CHKERRQ(ierr); 1714f0ae7da4SStefano 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"); 1715f0ae7da4SStefano 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"); 1716f0ae7da4SStefano Zampini if (!cong && x && b) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"A->rmap and A->cmap need to be congruent"); 1717b4319ba4SBarry Smith } 1718f0ae7da4SStefano Zampini #endif 17196e520ac8SStefano Zampini /* get locally owned rows */ 1720f0ae7da4SStefano Zampini ierr = PetscLayoutMapLocal_Private(A->rmap,n,rows,&len,&lrows,NULL);CHKERRQ(ierr); 17216e520ac8SStefano Zampini /* fix right hand side if needed */ 17226e520ac8SStefano Zampini if (x && b) { 17236e520ac8SStefano Zampini const PetscScalar *xx; 17246e520ac8SStefano Zampini PetscScalar *bb; 17252205254eSKarl Rupp 17266e520ac8SStefano Zampini ierr = VecGetArrayRead(x, &xx);CHKERRQ(ierr); 17276e520ac8SStefano Zampini ierr = VecGetArray(b, &bb);CHKERRQ(ierr); 17286e520ac8SStefano Zampini for (i=0;i<len;++i) bb[lrows[i]] = diag*xx[lrows[i]]; 17296e520ac8SStefano Zampini ierr = VecRestoreArrayRead(x, &xx);CHKERRQ(ierr); 17306e520ac8SStefano Zampini ierr = VecRestoreArray(b, &bb);CHKERRQ(ierr); 1731b4319ba4SBarry Smith } 17326e520ac8SStefano Zampini /* get rows associated to the local matrices */ 17333d996552SStefano Zampini ierr = MatISSetUpSF(A);CHKERRQ(ierr); 17346e520ac8SStefano Zampini ierr = MatGetSize(matis->A,&nl,NULL);CHKERRQ(ierr); 17356e520ac8SStefano Zampini ierr = PetscMemzero(matis->sf_leafdata,nl*sizeof(PetscInt));CHKERRQ(ierr); 17366e520ac8SStefano Zampini ierr = PetscMemzero(matis->sf_rootdata,A->rmap->n*sizeof(PetscInt));CHKERRQ(ierr); 17376e520ac8SStefano Zampini for (i=0;i<len;i++) matis->sf_rootdata[lrows[i]] = 1; 17386e520ac8SStefano Zampini ierr = PetscFree(lrows);CHKERRQ(ierr); 17396e520ac8SStefano Zampini ierr = PetscSFBcastBegin(matis->sf,MPIU_INT,matis->sf_rootdata,matis->sf_leafdata);CHKERRQ(ierr); 17406e520ac8SStefano Zampini ierr = PetscSFBcastEnd(matis->sf,MPIU_INT,matis->sf_rootdata,matis->sf_leafdata);CHKERRQ(ierr); 17416e520ac8SStefano Zampini ierr = PetscMalloc1(nl,&lrows);CHKERRQ(ierr); 17426e520ac8SStefano Zampini for (i=0,nr=0;i<nl;i++) if (matis->sf_leafdata[i]) lrows[nr++] = i; 1743f0ae7da4SStefano Zampini ierr = MatISZeroRowsColumnsLocal_Private(A,nr,lrows,diag,columns);CHKERRQ(ierr); 17446e520ac8SStefano Zampini ierr = PetscFree(lrows);CHKERRQ(ierr); 1745b4319ba4SBarry Smith PetscFunctionReturn(0); 1746b4319ba4SBarry Smith } 1747b4319ba4SBarry Smith 1748b4319ba4SBarry Smith #undef __FUNCT__ 1749f0ae7da4SStefano Zampini #define __FUNCT__ "MatZeroRows_IS" 1750f0ae7da4SStefano Zampini static PetscErrorCode MatZeroRows_IS(Mat A,PetscInt n,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 1751b4319ba4SBarry Smith { 1752b4319ba4SBarry Smith PetscErrorCode ierr; 1753b4319ba4SBarry Smith 1754b4319ba4SBarry Smith PetscFunctionBegin; 1755f0ae7da4SStefano Zampini ierr = MatZeroRowsColumns_Private_IS(A,n,rows,diag,x,b,PETSC_FALSE);CHKERRQ(ierr); 1756f0ae7da4SStefano Zampini PetscFunctionReturn(0); 1757f0ae7da4SStefano Zampini } 1758b4319ba4SBarry Smith 1759f0ae7da4SStefano Zampini #undef __FUNCT__ 1760f0ae7da4SStefano Zampini #define __FUNCT__ "MatZeroRowsColumns_IS" 1761f0ae7da4SStefano Zampini static PetscErrorCode MatZeroRowsColumns_IS(Mat A,PetscInt n,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 1762f0ae7da4SStefano Zampini { 1763f0ae7da4SStefano Zampini PetscErrorCode ierr; 1764f0ae7da4SStefano Zampini 1765f0ae7da4SStefano Zampini PetscFunctionBegin; 1766f0ae7da4SStefano Zampini ierr = MatZeroRowsColumns_Private_IS(A,n,rows,diag,x,b,PETSC_TRUE);CHKERRQ(ierr); 1767b4319ba4SBarry Smith PetscFunctionReturn(0); 1768b4319ba4SBarry Smith } 1769b4319ba4SBarry Smith 1770b4319ba4SBarry Smith #undef __FUNCT__ 1771b4319ba4SBarry Smith #define __FUNCT__ "MatAssemblyBegin_IS" 1772a8116848SStefano Zampini static PetscErrorCode MatAssemblyBegin_IS(Mat A,MatAssemblyType type) 1773b4319ba4SBarry Smith { 1774b4319ba4SBarry Smith Mat_IS *is = (Mat_IS*)A->data; 1775dfbe8321SBarry Smith PetscErrorCode ierr; 1776b4319ba4SBarry Smith 1777b4319ba4SBarry Smith PetscFunctionBegin; 1778b4319ba4SBarry Smith ierr = MatAssemblyBegin(is->A,type);CHKERRQ(ierr); 1779b4319ba4SBarry Smith PetscFunctionReturn(0); 1780b4319ba4SBarry Smith } 1781b4319ba4SBarry Smith 1782b4319ba4SBarry Smith #undef __FUNCT__ 1783b4319ba4SBarry Smith #define __FUNCT__ "MatAssemblyEnd_IS" 1784a8116848SStefano Zampini static PetscErrorCode MatAssemblyEnd_IS(Mat A,MatAssemblyType type) 1785b4319ba4SBarry Smith { 1786b4319ba4SBarry Smith Mat_IS *is = (Mat_IS*)A->data; 1787dfbe8321SBarry Smith PetscErrorCode ierr; 1788b4319ba4SBarry Smith 1789b4319ba4SBarry Smith PetscFunctionBegin; 1790b4319ba4SBarry Smith ierr = MatAssemblyEnd(is->A,type);CHKERRQ(ierr); 1791b4319ba4SBarry Smith PetscFunctionReturn(0); 1792b4319ba4SBarry Smith } 1793b4319ba4SBarry Smith 1794b4319ba4SBarry Smith #undef __FUNCT__ 1795b4319ba4SBarry Smith #define __FUNCT__ "MatISGetLocalMat_IS" 1796a8116848SStefano Zampini static PetscErrorCode MatISGetLocalMat_IS(Mat mat,Mat *local) 1797b4319ba4SBarry Smith { 1798b4319ba4SBarry Smith Mat_IS *is = (Mat_IS*)mat->data; 1799b4319ba4SBarry Smith 1800b4319ba4SBarry Smith PetscFunctionBegin; 1801b4319ba4SBarry Smith *local = is->A; 1802b4319ba4SBarry Smith PetscFunctionReturn(0); 1803b4319ba4SBarry Smith } 1804b4319ba4SBarry Smith 1805b4319ba4SBarry Smith #undef __FUNCT__ 1806b4319ba4SBarry Smith #define __FUNCT__ "MatISGetLocalMat" 1807b4319ba4SBarry Smith /*@ 1808b4319ba4SBarry Smith MatISGetLocalMat - Gets the local matrix stored inside a MATIS matrix. 1809b4319ba4SBarry Smith 1810b4319ba4SBarry Smith Input Parameter: 1811b4319ba4SBarry Smith . mat - the matrix 1812b4319ba4SBarry Smith 1813b4319ba4SBarry Smith Output Parameter: 1814eb82efa4SStefano Zampini . local - the local matrix 1815b4319ba4SBarry Smith 1816b4319ba4SBarry Smith Level: advanced 1817b4319ba4SBarry Smith 1818b4319ba4SBarry Smith Notes: 1819b4319ba4SBarry Smith This can be called if you have precomputed the nonzero structure of the 1820b4319ba4SBarry Smith matrix and want to provide it to the inner matrix object to improve the performance 1821b4319ba4SBarry Smith of the MatSetValues() operation. 1822b4319ba4SBarry Smith 1823b4319ba4SBarry Smith .seealso: MATIS 1824b4319ba4SBarry Smith @*/ 18257087cfbeSBarry Smith PetscErrorCode MatISGetLocalMat(Mat mat,Mat *local) 1826b4319ba4SBarry Smith { 18274ac538c5SBarry Smith PetscErrorCode ierr; 1828b4319ba4SBarry Smith 1829b4319ba4SBarry Smith PetscFunctionBegin; 18300700a824SBarry Smith PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1831b4319ba4SBarry Smith PetscValidPointer(local,2); 18324ac538c5SBarry Smith ierr = PetscUseMethod(mat,"MatISGetLocalMat_C",(Mat,Mat*),(mat,local));CHKERRQ(ierr); 1833b4319ba4SBarry Smith PetscFunctionReturn(0); 1834b4319ba4SBarry Smith } 1835b4319ba4SBarry Smith 18363b03a366Sstefano_zampini #undef __FUNCT__ 18373b03a366Sstefano_zampini #define __FUNCT__ "MatISSetLocalMat_IS" 1838a8116848SStefano Zampini static PetscErrorCode MatISSetLocalMat_IS(Mat mat,Mat local) 18393b03a366Sstefano_zampini { 18403b03a366Sstefano_zampini Mat_IS *is = (Mat_IS*)mat->data; 18413b03a366Sstefano_zampini PetscInt nrows,ncols,orows,ocols; 18423b03a366Sstefano_zampini PetscErrorCode ierr; 18433b03a366Sstefano_zampini 18443b03a366Sstefano_zampini PetscFunctionBegin; 18454e4c7dbeSStefano Zampini if (is->A) { 18463b03a366Sstefano_zampini ierr = MatGetSize(is->A,&orows,&ocols);CHKERRQ(ierr); 18473b03a366Sstefano_zampini ierr = MatGetSize(local,&nrows,&ncols);CHKERRQ(ierr); 1848f0ae7da4SStefano 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); 18494e4c7dbeSStefano Zampini } 18503b03a366Sstefano_zampini ierr = PetscObjectReference((PetscObject)local);CHKERRQ(ierr); 18513b03a366Sstefano_zampini ierr = MatDestroy(&is->A);CHKERRQ(ierr); 18523b03a366Sstefano_zampini is->A = local; 18533b03a366Sstefano_zampini PetscFunctionReturn(0); 18543b03a366Sstefano_zampini } 18553b03a366Sstefano_zampini 18563b03a366Sstefano_zampini #undef __FUNCT__ 18573b03a366Sstefano_zampini #define __FUNCT__ "MatISSetLocalMat" 18583b03a366Sstefano_zampini /*@ 1859eb82efa4SStefano Zampini MatISSetLocalMat - Replace the local matrix stored inside a MATIS object. 18603b03a366Sstefano_zampini 18613b03a366Sstefano_zampini Input Parameter: 18623b03a366Sstefano_zampini . mat - the matrix 1863eb82efa4SStefano Zampini . local - the local matrix 18643b03a366Sstefano_zampini 18653b03a366Sstefano_zampini Output Parameter: 18663b03a366Sstefano_zampini 18673b03a366Sstefano_zampini Level: advanced 18683b03a366Sstefano_zampini 18693b03a366Sstefano_zampini Notes: 18703b03a366Sstefano_zampini This can be called if you have precomputed the local matrix and 18713b03a366Sstefano_zampini want to provide it to the matrix object MATIS. 18723b03a366Sstefano_zampini 18733b03a366Sstefano_zampini .seealso: MATIS 18743b03a366Sstefano_zampini @*/ 18753b03a366Sstefano_zampini PetscErrorCode MatISSetLocalMat(Mat mat,Mat local) 18763b03a366Sstefano_zampini { 18773b03a366Sstefano_zampini PetscErrorCode ierr; 18783b03a366Sstefano_zampini 18793b03a366Sstefano_zampini PetscFunctionBegin; 18803b03a366Sstefano_zampini PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1881b7ce53b6SStefano Zampini PetscValidHeaderSpecific(local,MAT_CLASSID,2); 18823b03a366Sstefano_zampini ierr = PetscUseMethod(mat,"MatISSetLocalMat_C",(Mat,Mat),(mat,local));CHKERRQ(ierr); 18833b03a366Sstefano_zampini PetscFunctionReturn(0); 18843b03a366Sstefano_zampini } 18853b03a366Sstefano_zampini 18866726f965SBarry Smith #undef __FUNCT__ 18876726f965SBarry Smith #define __FUNCT__ "MatZeroEntries_IS" 1888a8116848SStefano Zampini static PetscErrorCode MatZeroEntries_IS(Mat A) 18896726f965SBarry Smith { 18906726f965SBarry Smith Mat_IS *a = (Mat_IS*)A->data; 18916726f965SBarry Smith PetscErrorCode ierr; 18926726f965SBarry Smith 18936726f965SBarry Smith PetscFunctionBegin; 18946726f965SBarry Smith ierr = MatZeroEntries(a->A);CHKERRQ(ierr); 18956726f965SBarry Smith PetscFunctionReturn(0); 18966726f965SBarry Smith } 18976726f965SBarry Smith 18986726f965SBarry Smith #undef __FUNCT__ 18992e74eeadSLisandro Dalcin #define __FUNCT__ "MatScale_IS" 1900a8116848SStefano Zampini static PetscErrorCode MatScale_IS(Mat A,PetscScalar a) 19012e74eeadSLisandro Dalcin { 19022e74eeadSLisandro Dalcin Mat_IS *is = (Mat_IS*)A->data; 19032e74eeadSLisandro Dalcin PetscErrorCode ierr; 19042e74eeadSLisandro Dalcin 19052e74eeadSLisandro Dalcin PetscFunctionBegin; 19062e74eeadSLisandro Dalcin ierr = MatScale(is->A,a);CHKERRQ(ierr); 19072e74eeadSLisandro Dalcin PetscFunctionReturn(0); 19082e74eeadSLisandro Dalcin } 19092e74eeadSLisandro Dalcin 19102e74eeadSLisandro Dalcin #undef __FUNCT__ 19112e74eeadSLisandro Dalcin #define __FUNCT__ "MatGetDiagonal_IS" 1912a8116848SStefano Zampini static PetscErrorCode MatGetDiagonal_IS(Mat A, Vec v) 19132e74eeadSLisandro Dalcin { 19142e74eeadSLisandro Dalcin Mat_IS *is = (Mat_IS*)A->data; 19152e74eeadSLisandro Dalcin PetscErrorCode ierr; 19162e74eeadSLisandro Dalcin 19172e74eeadSLisandro Dalcin PetscFunctionBegin; 19182e74eeadSLisandro Dalcin /* get diagonal of the local matrix */ 1919e176bc59SStefano Zampini ierr = MatGetDiagonal(is->A,is->y);CHKERRQ(ierr); 19202e74eeadSLisandro Dalcin 19212e74eeadSLisandro Dalcin /* scatter diagonal back into global vector */ 19222e74eeadSLisandro Dalcin ierr = VecSet(v,0);CHKERRQ(ierr); 1923e176bc59SStefano Zampini ierr = VecScatterBegin(is->rctx,is->y,v,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 1924e176bc59SStefano Zampini ierr = VecScatterEnd(is->rctx,is->y,v,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 19252e74eeadSLisandro Dalcin PetscFunctionReturn(0); 19262e74eeadSLisandro Dalcin } 19272e74eeadSLisandro Dalcin 19282e74eeadSLisandro Dalcin #undef __FUNCT__ 19296726f965SBarry Smith #define __FUNCT__ "MatSetOption_IS" 1930a8116848SStefano Zampini static PetscErrorCode MatSetOption_IS(Mat A,MatOption op,PetscBool flg) 19316726f965SBarry Smith { 19326726f965SBarry Smith Mat_IS *a = (Mat_IS*)A->data; 19336726f965SBarry Smith PetscErrorCode ierr; 19346726f965SBarry Smith 19356726f965SBarry Smith PetscFunctionBegin; 19364e0d8c25SBarry Smith ierr = MatSetOption(a->A,op,flg);CHKERRQ(ierr); 19376726f965SBarry Smith PetscFunctionReturn(0); 19386726f965SBarry Smith } 19396726f965SBarry Smith 1940284134d9SBarry Smith #undef __FUNCT__ 1941f26d0771SStefano Zampini #define __FUNCT__ "MatAXPY_IS" 1942f26d0771SStefano Zampini static PetscErrorCode MatAXPY_IS(Mat Y,PetscScalar a,Mat X,MatStructure str) 1943f26d0771SStefano Zampini { 1944f26d0771SStefano Zampini Mat_IS *y = (Mat_IS*)Y->data; 1945f26d0771SStefano Zampini Mat_IS *x; 1946f26d0771SStefano Zampini #if defined(PETSC_USE_DEBUG) 1947f26d0771SStefano Zampini PetscBool ismatis; 1948f26d0771SStefano Zampini #endif 1949f26d0771SStefano Zampini PetscErrorCode ierr; 1950f26d0771SStefano Zampini 1951f26d0771SStefano Zampini PetscFunctionBegin; 1952f26d0771SStefano Zampini #if defined(PETSC_USE_DEBUG) 1953f26d0771SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)X,MATIS,&ismatis);CHKERRQ(ierr); 1954f26d0771SStefano Zampini if (!ismatis) SETERRQ(PetscObjectComm((PetscObject)Y),PETSC_ERR_SUP,"Cannot call MatAXPY(Y,a,X,str) with X not of type MATIS"); 1955f26d0771SStefano Zampini #endif 1956f26d0771SStefano Zampini x = (Mat_IS*)X->data; 1957f26d0771SStefano Zampini ierr = MatAXPY(y->A,a,x->A,str);CHKERRQ(ierr); 1958f26d0771SStefano Zampini PetscFunctionReturn(0); 1959f26d0771SStefano Zampini } 1960f26d0771SStefano Zampini 1961f26d0771SStefano Zampini #undef __FUNCT__ 1962f26d0771SStefano Zampini #define __FUNCT__ "MatGetLocalSubMatrix_IS" 1963f26d0771SStefano Zampini static PetscErrorCode MatGetLocalSubMatrix_IS(Mat A,IS row,IS col,Mat *submat) 1964f26d0771SStefano Zampini { 1965f26d0771SStefano Zampini Mat lA; 1966f26d0771SStefano Zampini Mat_IS *matis; 1967f26d0771SStefano Zampini ISLocalToGlobalMapping rl2g,cl2g; 1968f26d0771SStefano Zampini IS is; 1969f26d0771SStefano Zampini const PetscInt *rg,*rl; 1970f26d0771SStefano Zampini PetscInt nrg; 1971f26d0771SStefano Zampini PetscInt N,M,nrl,i,*idxs; 1972f26d0771SStefano Zampini PetscErrorCode ierr; 1973f26d0771SStefano Zampini 1974f26d0771SStefano Zampini PetscFunctionBegin; 1975f26d0771SStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(A->rmap->mapping,&rg);CHKERRQ(ierr); 1976f26d0771SStefano Zampini ierr = ISGetLocalSize(row,&nrl);CHKERRQ(ierr); 1977f26d0771SStefano Zampini ierr = ISGetIndices(row,&rl);CHKERRQ(ierr); 1978f26d0771SStefano Zampini ierr = ISLocalToGlobalMappingGetSize(A->rmap->mapping,&nrg);CHKERRQ(ierr); 1979f26d0771SStefano Zampini #if defined(PETSC_USE_DEBUG) 1980f0ae7da4SStefano 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); 1981f26d0771SStefano Zampini #endif 1982f26d0771SStefano Zampini ierr = PetscMalloc1(nrg,&idxs);CHKERRQ(ierr); 1983f26d0771SStefano Zampini /* map from [0,nrl) to row */ 1984f26d0771SStefano Zampini for (i=0;i<nrl;i++) idxs[i] = rl[i]; 1985f26d0771SStefano Zampini #if defined(PETSC_USE_DEBUG) 1986f26d0771SStefano Zampini for (i=nrl;i<nrg;i++) idxs[i] = nrg; 1987f26d0771SStefano Zampini #else 1988f26d0771SStefano Zampini for (i=nrl;i<nrg;i++) idxs[i] = -1; 1989f26d0771SStefano Zampini #endif 1990f26d0771SStefano Zampini ierr = ISRestoreIndices(row,&rl);CHKERRQ(ierr); 1991f26d0771SStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(A->rmap->mapping,&rg);CHKERRQ(ierr); 1992f26d0771SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)A),nrg,idxs,PETSC_OWN_POINTER,&is);CHKERRQ(ierr); 1993f26d0771SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is,&rl2g);CHKERRQ(ierr); 1994f26d0771SStefano Zampini ierr = ISDestroy(&is);CHKERRQ(ierr); 1995f26d0771SStefano Zampini /* compute new l2g map for columns */ 1996f26d0771SStefano Zampini if (col != row || A->rmap->mapping != A->cmap->mapping) { 1997f26d0771SStefano Zampini const PetscInt *cg,*cl; 1998f26d0771SStefano Zampini PetscInt ncg; 1999f26d0771SStefano Zampini PetscInt ncl; 2000f26d0771SStefano Zampini 2001f26d0771SStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(A->cmap->mapping,&cg);CHKERRQ(ierr); 2002f26d0771SStefano Zampini ierr = ISGetLocalSize(col,&ncl);CHKERRQ(ierr); 2003f26d0771SStefano Zampini ierr = ISGetIndices(col,&cl);CHKERRQ(ierr); 2004f26d0771SStefano Zampini ierr = ISLocalToGlobalMappingGetSize(A->cmap->mapping,&ncg);CHKERRQ(ierr); 2005f26d0771SStefano Zampini #if defined(PETSC_USE_DEBUG) 2006f0ae7da4SStefano 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); 2007f26d0771SStefano Zampini #endif 2008f26d0771SStefano Zampini ierr = PetscMalloc1(ncg,&idxs);CHKERRQ(ierr); 2009f26d0771SStefano Zampini /* map from [0,ncl) to col */ 2010f26d0771SStefano Zampini for (i=0;i<ncl;i++) idxs[i] = cl[i]; 2011f26d0771SStefano Zampini #if defined(PETSC_USE_DEBUG) 2012f26d0771SStefano Zampini for (i=ncl;i<ncg;i++) idxs[i] = ncg; 2013f26d0771SStefano Zampini #else 2014f26d0771SStefano Zampini for (i=ncl;i<ncg;i++) idxs[i] = -1; 2015f26d0771SStefano Zampini #endif 2016f26d0771SStefano Zampini ierr = ISRestoreIndices(col,&cl);CHKERRQ(ierr); 2017f26d0771SStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(A->cmap->mapping,&cg);CHKERRQ(ierr); 2018f26d0771SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)A),ncg,idxs,PETSC_OWN_POINTER,&is);CHKERRQ(ierr); 2019f26d0771SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is,&cl2g);CHKERRQ(ierr); 2020f26d0771SStefano Zampini ierr = ISDestroy(&is);CHKERRQ(ierr); 2021f26d0771SStefano Zampini } else { 2022f26d0771SStefano Zampini ierr = PetscObjectReference((PetscObject)rl2g);CHKERRQ(ierr); 2023f26d0771SStefano Zampini cl2g = rl2g; 2024f26d0771SStefano Zampini } 2025f26d0771SStefano Zampini /* create the MATIS submatrix */ 2026f26d0771SStefano Zampini ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr); 2027f26d0771SStefano Zampini ierr = MatCreate(PetscObjectComm((PetscObject)A),submat);CHKERRQ(ierr); 2028f26d0771SStefano Zampini ierr = MatSetSizes(*submat,PETSC_DECIDE,PETSC_DECIDE,M,N);CHKERRQ(ierr); 2029f26d0771SStefano Zampini ierr = MatSetType(*submat,MATIS);CHKERRQ(ierr); 2030b0aa3428SStefano Zampini matis = (Mat_IS*)((*submat)->data); 2031f26d0771SStefano Zampini matis->islocalref = PETSC_TRUE; 2032f26d0771SStefano Zampini ierr = MatSetLocalToGlobalMapping(*submat,rl2g,cl2g);CHKERRQ(ierr); 2033f26d0771SStefano Zampini ierr = MatISGetLocalMat(A,&lA);CHKERRQ(ierr); 2034f26d0771SStefano Zampini ierr = MatISSetLocalMat(*submat,lA);CHKERRQ(ierr); 2035f26d0771SStefano Zampini ierr = MatSetUp(*submat);CHKERRQ(ierr); 2036f26d0771SStefano Zampini ierr = MatAssemblyBegin(*submat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2037f26d0771SStefano Zampini ierr = MatAssemblyEnd(*submat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2038f26d0771SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&rl2g);CHKERRQ(ierr); 2039f26d0771SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&cl2g);CHKERRQ(ierr); 2040f26d0771SStefano Zampini /* remove unsupported ops */ 2041f26d0771SStefano Zampini ierr = PetscMemzero((*submat)->ops,sizeof(struct _MatOps));CHKERRQ(ierr); 2042f26d0771SStefano Zampini (*submat)->ops->destroy = MatDestroy_IS; 2043f26d0771SStefano Zampini (*submat)->ops->setvalueslocal = MatSetValuesLocal_SubMat_IS; 2044f26d0771SStefano Zampini (*submat)->ops->setvaluesblockedlocal = MatSetValuesBlockedLocal_SubMat_IS; 2045f26d0771SStefano Zampini (*submat)->ops->assemblybegin = MatAssemblyBegin_IS; 2046f26d0771SStefano Zampini (*submat)->ops->assemblyend = MatAssemblyEnd_IS; 2047f26d0771SStefano Zampini PetscFunctionReturn(0); 2048f26d0771SStefano Zampini } 2049f26d0771SStefano Zampini 2050f26d0771SStefano Zampini #undef __FUNCT__ 2051284134d9SBarry Smith #define __FUNCT__ "MatCreateIS" 2052284134d9SBarry Smith /*@ 20533c212e90SHong Zhang MatCreateIS - Creates a "process" unassembled matrix, assembled on each 2054284134d9SBarry Smith process but not across processes. 2055284134d9SBarry Smith 2056284134d9SBarry Smith Input Parameters: 2057284134d9SBarry Smith + comm - MPI communicator that will share the matrix 2058e176bc59SStefano Zampini . bs - block size of the matrix 2059df3898eeSBarry Smith . m,n,M,N - local and/or global sizes of the left and right vector used in matrix vector products 2060e176bc59SStefano Zampini . rmap - local to global map for rows 2061e176bc59SStefano Zampini - cmap - local to global map for cols 2062284134d9SBarry Smith 2063284134d9SBarry Smith Output Parameter: 2064284134d9SBarry Smith . A - the resulting matrix 2065284134d9SBarry Smith 20668e6c10adSSatish Balay Level: advanced 20678e6c10adSSatish Balay 20683c212e90SHong Zhang Notes: See MATIS for more details. 20696fdf41d1SStefano Zampini m and n are NOT related to the size of the map; they represent the size of the local parts of the vectors 20706fdf41d1SStefano Zampini used in MatMult operations. The sizes of rmap and cmap define the size of the local matrices. 20713c212e90SHong Zhang If either rmap or cmap are NULL, then the matrix is assumed to be square. 2072284134d9SBarry Smith 2073284134d9SBarry Smith .seealso: MATIS, MatSetLocalToGlobalMapping() 2074284134d9SBarry Smith @*/ 2075e176bc59SStefano Zampini PetscErrorCode MatCreateIS(MPI_Comm comm,PetscInt bs,PetscInt m,PetscInt n,PetscInt M,PetscInt N,ISLocalToGlobalMapping rmap,ISLocalToGlobalMapping cmap,Mat *A) 2076284134d9SBarry Smith { 2077284134d9SBarry Smith PetscErrorCode ierr; 2078284134d9SBarry Smith 2079284134d9SBarry Smith PetscFunctionBegin; 20806fdf41d1SStefano Zampini if (!rmap && !cmap) SETERRQ(comm,PETSC_ERR_USER,"You need to provide at least one of the mappings"); 2081284134d9SBarry Smith ierr = MatCreate(comm,A);CHKERRQ(ierr); 20826fdf41d1SStefano Zampini if (bs > 0) { 2083d3ee2243SStefano Zampini ierr = MatSetBlockSize(*A,bs);CHKERRQ(ierr); 20846fdf41d1SStefano Zampini } 2085284134d9SBarry Smith ierr = MatSetSizes(*A,m,n,M,N);CHKERRQ(ierr); 2086284134d9SBarry Smith ierr = MatSetType(*A,MATIS);CHKERRQ(ierr); 2087e176bc59SStefano Zampini if (rmap && cmap) { 2088e176bc59SStefano Zampini ierr = MatSetLocalToGlobalMapping(*A,rmap,cmap);CHKERRQ(ierr); 2089e176bc59SStefano Zampini } else if (!rmap) { 2090e176bc59SStefano Zampini ierr = MatSetLocalToGlobalMapping(*A,cmap,cmap);CHKERRQ(ierr); 2091e176bc59SStefano Zampini } else { 2092e176bc59SStefano Zampini ierr = MatSetLocalToGlobalMapping(*A,rmap,rmap);CHKERRQ(ierr); 2093e176bc59SStefano Zampini } 2094284134d9SBarry Smith PetscFunctionReturn(0); 2095284134d9SBarry Smith } 2096284134d9SBarry Smith 2097b4319ba4SBarry Smith /*MC 2098f26d0771SStefano Zampini MATIS - MATIS = "is" - A matrix type to be used for using the non-overlapping domain decomposition methods (e.g. PCBDDC or KSPFETIDP). 2099b4319ba4SBarry Smith This stores the matrices in globally unassembled form. Each processor 2100b4319ba4SBarry Smith assembles only its local Neumann problem and the parallel matrix vector 2101b4319ba4SBarry Smith product is handled "implicitly". 2102b4319ba4SBarry Smith 2103b4319ba4SBarry Smith Operations Provided: 21046726f965SBarry Smith + MatMult() 21052e74eeadSLisandro Dalcin . MatMultAdd() 21062e74eeadSLisandro Dalcin . MatMultTranspose() 21072e74eeadSLisandro Dalcin . MatMultTransposeAdd() 21086726f965SBarry Smith . MatZeroEntries() 21096726f965SBarry Smith . MatSetOption() 21102e74eeadSLisandro Dalcin . MatZeroRows() 21112e74eeadSLisandro Dalcin . MatSetValues() 211297563a80SStefano Zampini . MatSetValuesBlocked() 21136726f965SBarry Smith . MatSetValuesLocal() 211497563a80SStefano Zampini . MatSetValuesBlockedLocal() 21152e74eeadSLisandro Dalcin . MatScale() 21162e74eeadSLisandro Dalcin . MatGetDiagonal() 21172b404112SStefano Zampini . MatMissingDiagonal() 21182b404112SStefano Zampini . MatDuplicate() 21192b404112SStefano Zampini . MatCopy() 2120f26d0771SStefano Zampini . MatAXPY() 2121f26d0771SStefano Zampini . MatGetSubMatrix() 2122f26d0771SStefano Zampini . MatGetLocalSubMatrix() 2123d7f69cd0SStefano Zampini . MatTranspose() 21246726f965SBarry Smith - MatSetLocalToGlobalMapping() 2125b4319ba4SBarry Smith 2126b4319ba4SBarry Smith Options Database Keys: 2127b4319ba4SBarry Smith . -mat_type is - sets the matrix type to "is" during a call to MatSetFromOptions() 2128b4319ba4SBarry Smith 2129b4319ba4SBarry Smith Notes: Options prefix for the inner matrix are given by -is_mat_xxx 2130b4319ba4SBarry Smith 2131b4319ba4SBarry Smith You must call MatSetLocalToGlobalMapping() before using this matrix type. 2132b4319ba4SBarry Smith 2133b4319ba4SBarry Smith You can do matrix preallocation on the local matrix after you obtain it with 2134eb82efa4SStefano Zampini MatISGetLocalMat(); otherwise, you could use MatISSetPreallocation() 2135b4319ba4SBarry Smith 2136b4319ba4SBarry Smith Level: advanced 2137b4319ba4SBarry Smith 2138f26d0771SStefano Zampini .seealso: Mat, MatISGetLocalMat(), MatSetLocalToGlobalMapping(), MatISSetPreallocation(), MatCreateIS(), PCBDDC, KSPFETIDP 2139b4319ba4SBarry Smith 2140b4319ba4SBarry Smith M*/ 2141b4319ba4SBarry Smith 2142b4319ba4SBarry Smith #undef __FUNCT__ 2143b4319ba4SBarry Smith #define __FUNCT__ "MatCreate_IS" 21448cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatCreate_IS(Mat A) 2145b4319ba4SBarry Smith { 2146dfbe8321SBarry Smith PetscErrorCode ierr; 2147b4319ba4SBarry Smith Mat_IS *b; 2148b4319ba4SBarry Smith 2149b4319ba4SBarry Smith PetscFunctionBegin; 2150b00a9115SJed Brown ierr = PetscNewLog(A,&b);CHKERRQ(ierr); 2151b4319ba4SBarry Smith A->data = (void*)b; 2152b4319ba4SBarry Smith 2153e176bc59SStefano Zampini /* matrix ops */ 2154e176bc59SStefano Zampini ierr = PetscMemzero(A->ops,sizeof(struct _MatOps));CHKERRQ(ierr); 2155b4319ba4SBarry Smith A->ops->mult = MatMult_IS; 21562e74eeadSLisandro Dalcin A->ops->multadd = MatMultAdd_IS; 21572e74eeadSLisandro Dalcin A->ops->multtranspose = MatMultTranspose_IS; 21582e74eeadSLisandro Dalcin A->ops->multtransposeadd = MatMultTransposeAdd_IS; 2159b4319ba4SBarry Smith A->ops->destroy = MatDestroy_IS; 2160b4319ba4SBarry Smith A->ops->setlocaltoglobalmapping = MatSetLocalToGlobalMapping_IS; 21612e74eeadSLisandro Dalcin A->ops->setvalues = MatSetValues_IS; 216298921651SStefano Zampini A->ops->setvaluesblocked = MatSetValuesBlocked_IS; 2163b4319ba4SBarry Smith A->ops->setvalueslocal = MatSetValuesLocal_IS; 2164f0006bf2SLisandro Dalcin A->ops->setvaluesblockedlocal = MatSetValuesBlockedLocal_IS; 21652e74eeadSLisandro Dalcin A->ops->zerorows = MatZeroRows_IS; 2166f0ae7da4SStefano Zampini A->ops->zerorowscolumns = MatZeroRowsColumns_IS; 2167b4319ba4SBarry Smith A->ops->assemblybegin = MatAssemblyBegin_IS; 2168b4319ba4SBarry Smith A->ops->assemblyend = MatAssemblyEnd_IS; 2169b4319ba4SBarry Smith A->ops->view = MatView_IS; 21706726f965SBarry Smith A->ops->zeroentries = MatZeroEntries_IS; 21712e74eeadSLisandro Dalcin A->ops->scale = MatScale_IS; 21722e74eeadSLisandro Dalcin A->ops->getdiagonal = MatGetDiagonal_IS; 21736726f965SBarry Smith A->ops->setoption = MatSetOption_IS; 217469796d55SStefano Zampini A->ops->ishermitian = MatIsHermitian_IS; 217569796d55SStefano Zampini A->ops->issymmetric = MatIsSymmetric_IS; 217645471136SStefano Zampini A->ops->isstructurallysymmetric = MatIsStructurallySymmetric_IS; 2177ad6194a2SStefano Zampini A->ops->duplicate = MatDuplicate_IS; 21786bd84002SStefano Zampini A->ops->missingdiagonal = MatMissingDiagonal_IS; 21792b404112SStefano Zampini A->ops->copy = MatCopy_IS; 2180659959c5SStefano Zampini A->ops->getlocalsubmatrix = MatGetLocalSubMatrix_IS; 2181a8116848SStefano Zampini A->ops->getsubmatrix = MatGetSubMatrix_IS; 2182f26d0771SStefano Zampini A->ops->axpy = MatAXPY_IS; 21833fd1c9e7SStefano Zampini A->ops->diagonalset = MatDiagonalSet_IS; 21843fd1c9e7SStefano Zampini A->ops->shift = MatShift_IS; 2185d7f69cd0SStefano Zampini A->ops->transpose = MatTranspose_IS; 2186b4319ba4SBarry Smith 2187b7ce53b6SStefano Zampini /* special MATIS functions */ 2188bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatISGetLocalMat_C",MatISGetLocalMat_IS);CHKERRQ(ierr); 2189bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatISSetLocalMat_C",MatISSetLocalMat_IS);CHKERRQ(ierr); 2190b7ce53b6SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatISGetMPIXAIJ_C",MatISGetMPIXAIJ_IS);CHKERRQ(ierr); 21912e1947a5SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatISSetPreallocation_C",MatISSetPreallocation_IS);CHKERRQ(ierr); 2192cf0a3239SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatISSetUpSF_C",MatISSetUpSF_IS);CHKERRQ(ierr); 219317667f90SBarry Smith ierr = PetscObjectChangeTypeName((PetscObject)A,MATIS);CHKERRQ(ierr); 2194b4319ba4SBarry Smith PetscFunctionReturn(0); 2195b4319ba4SBarry Smith } 2196