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*/ 1128f4e0baSStefano Zampini 12f26d0771SStefano Zampini #define MATIS_MAX_ENTRIES_INSERTION 2048 13f26d0771SStefano Zampini 14a72627d2SStefano Zampini static PetscErrorCode MatISComputeSF_Private(Mat); 15a72627d2SStefano Zampini 1628f4e0baSStefano Zampini #undef __FUNCT__ 17d7f69cd0SStefano Zampini #define __FUNCT__ "MatTranspose_IS" 18d7f69cd0SStefano Zampini PetscErrorCode MatTranspose_IS(Mat A,MatReuse reuse,Mat *B) 19d7f69cd0SStefano Zampini { 20d7f69cd0SStefano Zampini Mat C,lC,lA; 21d7f69cd0SStefano Zampini ISLocalToGlobalMapping rl2g,cl2g; 22d7f69cd0SStefano Zampini PetscBool notset = PETSC_FALSE,cong = PETSC_TRUE; 23d7f69cd0SStefano Zampini PetscErrorCode ierr; 24d7f69cd0SStefano Zampini 25d7f69cd0SStefano Zampini PetscFunctionBegin; 26d7f69cd0SStefano Zampini if (reuse == MAT_REUSE_MATRIX) { 27d7f69cd0SStefano Zampini PetscBool rcong,ccong; 28d7f69cd0SStefano Zampini 29d7f69cd0SStefano Zampini ierr = PetscLayoutCompare((*B)->cmap,A->rmap,&rcong);CHKERRQ(ierr); 30d7f69cd0SStefano Zampini ierr = PetscLayoutCompare((*B)->rmap,A->cmap,&ccong);CHKERRQ(ierr); 31fa520230SStefano Zampini cong = (PetscBool)(rcong || ccong); 32d7f69cd0SStefano Zampini } 33d7f69cd0SStefano Zampini if (reuse == MAT_INITIAL_MATRIX || *B == A || !cong) { 34d7f69cd0SStefano Zampini ierr = MatCreate(PetscObjectComm((PetscObject)A),&C);CHKERRQ(ierr); 35d7f69cd0SStefano Zampini } else { 36d7f69cd0SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)*B,MATIS,¬set);CHKERRQ(ierr); 37d7f69cd0SStefano Zampini C = *B; 38d7f69cd0SStefano Zampini } 39d7f69cd0SStefano Zampini 40d7f69cd0SStefano Zampini if (!notset) { 41d7f69cd0SStefano Zampini ierr = MatSetSizes(C,A->cmap->n,A->rmap->n,A->cmap->N,A->rmap->N);CHKERRQ(ierr); 42d7f69cd0SStefano Zampini ierr = MatSetBlockSizes(C,PetscAbs(A->cmap->bs),PetscAbs(A->rmap->bs));CHKERRQ(ierr); 43d7f69cd0SStefano Zampini ierr = MatSetType(C,MATIS);CHKERRQ(ierr); 44d7f69cd0SStefano Zampini ierr = MatGetLocalToGlobalMapping(A,&rl2g,&cl2g);CHKERRQ(ierr); 45d7f69cd0SStefano Zampini ierr = MatSetLocalToGlobalMapping(C,cl2g,rl2g);CHKERRQ(ierr); 46d7f69cd0SStefano Zampini } 47d7f69cd0SStefano Zampini 48d7f69cd0SStefano Zampini /* perform local transposition */ 49d7f69cd0SStefano Zampini ierr = MatISGetLocalMat(A,&lA);CHKERRQ(ierr); 50d7f69cd0SStefano Zampini ierr = MatTranspose(lA,MAT_INITIAL_MATRIX,&lC);CHKERRQ(ierr); 51d7f69cd0SStefano Zampini ierr = MatISSetLocalMat(C,lC);CHKERRQ(ierr); 52d7f69cd0SStefano Zampini ierr = MatDestroy(&lC);CHKERRQ(ierr); 53d7f69cd0SStefano Zampini 54d7f69cd0SStefano Zampini ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 55d7f69cd0SStefano Zampini ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 56d7f69cd0SStefano Zampini 57d7f69cd0SStefano Zampini if (reuse == MAT_INITIAL_MATRIX || *B != A) { 58d7f69cd0SStefano Zampini if (!cong) { 59d7f69cd0SStefano Zampini ierr = MatDestroy(B);CHKERRQ(ierr); 60d7f69cd0SStefano Zampini } 61d7f69cd0SStefano Zampini *B = C; 62d7f69cd0SStefano Zampini } else { 63d7f69cd0SStefano Zampini ierr = MatHeaderMerge(A,&C);CHKERRQ(ierr); 64d7f69cd0SStefano Zampini } 65d7f69cd0SStefano Zampini PetscFunctionReturn(0); 66d7f69cd0SStefano Zampini } 67d7f69cd0SStefano Zampini 68d7f69cd0SStefano Zampini #undef __FUNCT__ 693fd1c9e7SStefano Zampini #define __FUNCT__ "MatDiagonalSet_IS" 703fd1c9e7SStefano Zampini PetscErrorCode MatDiagonalSet_IS(Mat A,Vec D,InsertMode insmode) 713fd1c9e7SStefano Zampini { 723fd1c9e7SStefano Zampini Mat_IS *is = (Mat_IS*)A->data; 733fd1c9e7SStefano Zampini PetscErrorCode ierr; 743fd1c9e7SStefano Zampini 753fd1c9e7SStefano Zampini PetscFunctionBegin; 763fd1c9e7SStefano Zampini if (!D) { /* this code branch is used by MatShift_IS */ 773fd1c9e7SStefano Zampini ierr = VecSet(is->y,1.);CHKERRQ(ierr); 783fd1c9e7SStefano Zampini } else { 793fd1c9e7SStefano Zampini ierr = VecScatterBegin(is->rctx,D,is->y,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 803fd1c9e7SStefano Zampini ierr = VecScatterEnd(is->rctx,D,is->y,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 813fd1c9e7SStefano Zampini } 823fd1c9e7SStefano Zampini ierr = VecPointwiseDivide(is->y,is->y,is->counter);CHKERRQ(ierr); 833fd1c9e7SStefano Zampini ierr = MatDiagonalSet(is->A,is->y,insmode);CHKERRQ(ierr); 843fd1c9e7SStefano Zampini PetscFunctionReturn(0); 853fd1c9e7SStefano Zampini } 863fd1c9e7SStefano Zampini 873fd1c9e7SStefano Zampini #undef __FUNCT__ 883fd1c9e7SStefano Zampini #define __FUNCT__ "MatShift_IS" 893fd1c9e7SStefano Zampini PetscErrorCode MatShift_IS(Mat A,PetscScalar a) 903fd1c9e7SStefano Zampini { 913fd1c9e7SStefano Zampini PetscErrorCode ierr; 923fd1c9e7SStefano Zampini 933fd1c9e7SStefano Zampini PetscFunctionBegin; 943fd1c9e7SStefano Zampini ierr = MatDiagonalSet_IS(A,NULL,ADD_VALUES);CHKERRQ(ierr); 953fd1c9e7SStefano Zampini PetscFunctionReturn(0); 963fd1c9e7SStefano Zampini } 973fd1c9e7SStefano Zampini 983fd1c9e7SStefano Zampini #undef __FUNCT__ 99f26d0771SStefano Zampini #define __FUNCT__ "MatSetValuesLocal_SubMat_IS" 100f26d0771SStefano Zampini static PetscErrorCode MatSetValuesLocal_SubMat_IS(Mat A,PetscInt m,const PetscInt *rows, PetscInt n,const PetscInt *cols,const PetscScalar *values,InsertMode addv) 101f26d0771SStefano Zampini { 102f26d0771SStefano Zampini PetscErrorCode ierr; 103f26d0771SStefano Zampini Mat_IS *is = (Mat_IS*)A->data; 104f26d0771SStefano Zampini PetscInt rows_l[MATIS_MAX_ENTRIES_INSERTION],cols_l[MATIS_MAX_ENTRIES_INSERTION]; 105f26d0771SStefano Zampini 106f26d0771SStefano Zampini PetscFunctionBegin; 107f26d0771SStefano Zampini #if defined(PETSC_USE_DEBUG) 108f26d0771SStefano 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); 109f26d0771SStefano Zampini #endif 110f26d0771SStefano Zampini ierr = ISLocalToGlobalMappingApply(A->rmap->mapping,m,rows,rows_l);CHKERRQ(ierr); 111f26d0771SStefano Zampini ierr = ISLocalToGlobalMappingApply(A->cmap->mapping,n,cols,cols_l);CHKERRQ(ierr); 112f26d0771SStefano Zampini ierr = MatSetValues(is->A,m,rows_l,n,cols_l,values,addv);CHKERRQ(ierr); 113f26d0771SStefano Zampini PetscFunctionReturn(0); 114f26d0771SStefano Zampini } 115f26d0771SStefano Zampini 116f26d0771SStefano Zampini #undef __FUNCT__ 117f26d0771SStefano Zampini #define __FUNCT__ "MatSetValuesBlockedLocal_SubMat_IS" 118f26d0771SStefano Zampini static PetscErrorCode MatSetValuesBlockedLocal_SubMat_IS(Mat A,PetscInt m,const PetscInt *rows, PetscInt n,const PetscInt *cols,const PetscScalar *values,InsertMode addv) 119f26d0771SStefano Zampini { 120f26d0771SStefano Zampini PetscErrorCode ierr; 121f26d0771SStefano Zampini Mat_IS *is = (Mat_IS*)A->data; 122f26d0771SStefano Zampini PetscInt rows_l[MATIS_MAX_ENTRIES_INSERTION],cols_l[MATIS_MAX_ENTRIES_INSERTION]; 123f26d0771SStefano Zampini 124f26d0771SStefano Zampini PetscFunctionBegin; 125f26d0771SStefano Zampini #if defined(PETSC_USE_DEBUG) 126f26d0771SStefano 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); 127f26d0771SStefano Zampini #endif 128f26d0771SStefano Zampini ierr = ISLocalToGlobalMappingApplyBlock(A->rmap->mapping,m,rows,rows_l);CHKERRQ(ierr); 129f26d0771SStefano Zampini ierr = ISLocalToGlobalMappingApplyBlock(A->cmap->mapping,n,cols,cols_l);CHKERRQ(ierr); 130f26d0771SStefano Zampini ierr = MatSetValuesBlocked(is->A,m,rows_l,n,cols_l,values,addv);CHKERRQ(ierr); 131f26d0771SStefano Zampini PetscFunctionReturn(0); 132f26d0771SStefano Zampini } 133f26d0771SStefano Zampini 134f26d0771SStefano Zampini #undef __FUNCT__ 135a8116848SStefano Zampini #define __FUNCT__ "PetscLayoutMapLocal_Private" 136f0ae7da4SStefano Zampini static PetscErrorCode PetscLayoutMapLocal_Private(PetscLayout map,PetscInt N,const PetscInt idxs[], PetscInt *on,PetscInt **oidxs,PetscInt **ogidxs) 137a8116848SStefano Zampini { 138a8116848SStefano Zampini PetscInt *owners = map->range; 139a8116848SStefano Zampini PetscInt n = map->n; 140a8116848SStefano Zampini PetscSF sf; 141a8116848SStefano Zampini PetscInt *lidxs,*work = NULL; 142a8116848SStefano Zampini PetscSFNode *ridxs; 143a8116848SStefano Zampini PetscMPIInt rank; 144a8116848SStefano Zampini PetscInt r, p = 0, len = 0; 145a8116848SStefano Zampini PetscErrorCode ierr; 146a8116848SStefano Zampini 147a8116848SStefano Zampini PetscFunctionBegin; 148*fd3a879cSJed Brown if (on) *on = 0; /* squelch -Wmaybe-uninitialized */ 149a8116848SStefano Zampini /* Create SF where leaves are input idxs and roots are owned idxs (code adapted from MatZeroRowsMapLocal_Private) */ 150a8116848SStefano Zampini ierr = MPI_Comm_rank(map->comm,&rank);CHKERRQ(ierr); 151a8116848SStefano Zampini ierr = PetscMalloc1(n,&lidxs);CHKERRQ(ierr); 152a8116848SStefano Zampini for (r = 0; r < n; ++r) lidxs[r] = -1; 153a8116848SStefano Zampini ierr = PetscMalloc1(N,&ridxs);CHKERRQ(ierr); 154a8116848SStefano Zampini for (r = 0; r < N; ++r) { 155a8116848SStefano Zampini const PetscInt idx = idxs[r]; 156a8116848SStefano 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); 157a8116848SStefano Zampini if (idx < owners[p] || owners[p+1] <= idx) { /* short-circuit the search if the last p owns this idx too */ 158a8116848SStefano Zampini ierr = PetscLayoutFindOwner(map,idx,&p);CHKERRQ(ierr); 159a8116848SStefano Zampini } 160a8116848SStefano Zampini ridxs[r].rank = p; 161a8116848SStefano Zampini ridxs[r].index = idxs[r] - owners[p]; 162a8116848SStefano Zampini } 163a8116848SStefano Zampini ierr = PetscSFCreate(map->comm,&sf);CHKERRQ(ierr); 164a8116848SStefano Zampini ierr = PetscSFSetGraph(sf,n,N,NULL,PETSC_OWN_POINTER,ridxs,PETSC_OWN_POINTER);CHKERRQ(ierr); 165a8116848SStefano Zampini ierr = PetscSFReduceBegin(sf,MPIU_INT,(PetscInt*)idxs,lidxs,MPI_LOR);CHKERRQ(ierr); 166a8116848SStefano Zampini ierr = PetscSFReduceEnd(sf,MPIU_INT,(PetscInt*)idxs,lidxs,MPI_LOR);CHKERRQ(ierr); 167f0ae7da4SStefano Zampini if (ogidxs) { /* communicate global idxs */ 168a8116848SStefano Zampini PetscInt cum = 0,start,*work2; 169f0ae7da4SStefano Zampini 170f0ae7da4SStefano Zampini ierr = PetscMalloc1(n,&work);CHKERRQ(ierr); 171a8116848SStefano Zampini ierr = PetscCalloc1(N,&work2);CHKERRQ(ierr); 172a8116848SStefano Zampini for (r = 0; r < N; ++r) if (idxs[r] >=0) cum++; 173a8116848SStefano Zampini ierr = MPI_Scan(&cum,&start,1,MPIU_INT,MPI_SUM,map->comm);CHKERRQ(ierr); 174a8116848SStefano Zampini start -= cum; 175a8116848SStefano Zampini cum = 0; 176a8116848SStefano Zampini for (r = 0; r < N; ++r) if (idxs[r] >=0) work2[r] = start+cum++; 177a8116848SStefano Zampini ierr = PetscSFReduceBegin(sf,MPIU_INT,work2,work,MPIU_REPLACE);CHKERRQ(ierr); 178a8116848SStefano Zampini ierr = PetscSFReduceEnd(sf,MPIU_INT,work2,work,MPIU_REPLACE);CHKERRQ(ierr); 179a8116848SStefano Zampini ierr = PetscFree(work2);CHKERRQ(ierr); 180a8116848SStefano Zampini } 181a8116848SStefano Zampini ierr = PetscSFDestroy(&sf);CHKERRQ(ierr); 182a8116848SStefano Zampini /* Compress and put in indices */ 183a8116848SStefano Zampini for (r = 0; r < n; ++r) 184a8116848SStefano Zampini if (lidxs[r] >= 0) { 185a8116848SStefano Zampini if (work) work[len] = work[r]; 186a8116848SStefano Zampini lidxs[len++] = r; 187a8116848SStefano Zampini } 188a8116848SStefano Zampini if (on) *on = len; 189a8116848SStefano Zampini if (oidxs) *oidxs = lidxs; 190a8116848SStefano Zampini if (ogidxs) *ogidxs = work; 191a8116848SStefano Zampini PetscFunctionReturn(0); 192a8116848SStefano Zampini } 193a8116848SStefano Zampini 194a8116848SStefano Zampini #undef __FUNCT__ 195a8116848SStefano Zampini #define __FUNCT__ "MatGetSubMatrix_IS" 196a8116848SStefano Zampini static PetscErrorCode MatGetSubMatrix_IS(Mat mat,IS irow,IS icol,MatReuse scall,Mat *newmat) 197a8116848SStefano Zampini { 198a8116848SStefano Zampini Mat locmat,newlocmat; 199a8116848SStefano Zampini Mat_IS *newmatis; 200a8116848SStefano Zampini #if defined(PETSC_USE_DEBUG) 201a8116848SStefano Zampini Vec rtest,ltest; 202a8116848SStefano Zampini const PetscScalar *array; 203a8116848SStefano Zampini #endif 204a8116848SStefano Zampini const PetscInt *idxs; 205a8116848SStefano Zampini PetscInt i,m,n; 206a8116848SStefano Zampini PetscErrorCode ierr; 207a8116848SStefano Zampini 208a8116848SStefano Zampini PetscFunctionBegin; 209a8116848SStefano Zampini if (scall == MAT_REUSE_MATRIX) { 210a8116848SStefano Zampini PetscBool ismatis; 211a8116848SStefano Zampini 212a8116848SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)*newmat,MATIS,&ismatis);CHKERRQ(ierr); 213a8116848SStefano Zampini if (!ismatis) SETERRQ(PetscObjectComm((PetscObject)*newmat),PETSC_ERR_ARG_WRONG,"Cannot reuse matrix! Not of MATIS type"); 214a8116848SStefano Zampini newmatis = (Mat_IS*)(*newmat)->data; 215a8116848SStefano Zampini if (!newmatis->getsub_ris) SETERRQ(PetscObjectComm((PetscObject)*newmat),PETSC_ERR_ARG_WRONG,"Cannot reuse matrix! Misses local row IS"); 216a8116848SStefano Zampini if (!newmatis->getsub_cis) SETERRQ(PetscObjectComm((PetscObject)*newmat),PETSC_ERR_ARG_WRONG,"Cannot reuse matrix! Misses local col IS"); 217a8116848SStefano Zampini } 218a8116848SStefano Zampini /* irow and icol may not have duplicate entries */ 219a8116848SStefano Zampini #if defined(PETSC_USE_DEBUG) 220a8116848SStefano Zampini ierr = MatCreateVecs(mat,<est,&rtest);CHKERRQ(ierr); 221a8116848SStefano Zampini ierr = ISGetLocalSize(irow,&n);CHKERRQ(ierr); 222a8116848SStefano Zampini ierr = ISGetIndices(irow,&idxs);CHKERRQ(ierr); 223a8116848SStefano Zampini for (i=0;i<n;i++) { 224a8116848SStefano Zampini ierr = VecSetValue(rtest,idxs[i],1.0,ADD_VALUES);CHKERRQ(ierr); 225a8116848SStefano Zampini } 226a8116848SStefano Zampini ierr = VecAssemblyBegin(rtest);CHKERRQ(ierr); 227a8116848SStefano Zampini ierr = VecAssemblyEnd(rtest);CHKERRQ(ierr); 228a8116848SStefano Zampini ierr = VecGetLocalSize(rtest,&n);CHKERRQ(ierr); 229a8116848SStefano Zampini ierr = VecGetOwnershipRange(rtest,&m,NULL);CHKERRQ(ierr); 230a8116848SStefano Zampini ierr = VecGetArrayRead(rtest,&array);CHKERRQ(ierr); 231fd479f66SMatthew 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])); 232a8116848SStefano Zampini ierr = VecRestoreArrayRead(rtest,&array);CHKERRQ(ierr); 233a8116848SStefano Zampini ierr = ISRestoreIndices(irow,&idxs);CHKERRQ(ierr); 234a8116848SStefano Zampini ierr = ISGetLocalSize(icol,&n);CHKERRQ(ierr); 235a8116848SStefano Zampini ierr = ISGetIndices(icol,&idxs);CHKERRQ(ierr); 236a8116848SStefano Zampini for (i=0;i<n;i++) { 237a8116848SStefano Zampini ierr = VecSetValue(ltest,idxs[i],1.0,ADD_VALUES);CHKERRQ(ierr); 238a8116848SStefano Zampini } 239a8116848SStefano Zampini ierr = VecAssemblyBegin(ltest);CHKERRQ(ierr); 240a8116848SStefano Zampini ierr = VecAssemblyEnd(ltest);CHKERRQ(ierr); 241a8116848SStefano Zampini ierr = VecGetLocalSize(ltest,&n);CHKERRQ(ierr); 242a8116848SStefano Zampini ierr = VecGetOwnershipRange(ltest,&m,NULL);CHKERRQ(ierr); 243a8116848SStefano Zampini ierr = VecGetArrayRead(ltest,&array);CHKERRQ(ierr); 244fd479f66SMatthew 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])); 245a8116848SStefano Zampini ierr = VecRestoreArrayRead(ltest,&array);CHKERRQ(ierr); 246a8116848SStefano Zampini ierr = ISRestoreIndices(icol,&idxs);CHKERRQ(ierr); 247a8116848SStefano Zampini ierr = VecDestroy(&rtest);CHKERRQ(ierr); 248a8116848SStefano Zampini ierr = VecDestroy(<est);CHKERRQ(ierr); 249a8116848SStefano Zampini #endif 250a8116848SStefano Zampini if (scall == MAT_INITIAL_MATRIX) { 251a8116848SStefano Zampini Mat_IS *matis = (Mat_IS*)mat->data; 252a8116848SStefano Zampini ISLocalToGlobalMapping rl2g; 253a8116848SStefano Zampini IS is; 254a8116848SStefano Zampini PetscInt *lidxs,*lgidxs,*newgidxs; 2556dd40735SStefano Zampini PetscInt ll,newloc; 256a8116848SStefano Zampini MPI_Comm comm; 257a8116848SStefano Zampini 258a8116848SStefano Zampini ierr = PetscObjectGetComm((PetscObject)mat,&comm);CHKERRQ(ierr); 259a8116848SStefano Zampini ierr = ISGetLocalSize(irow,&m);CHKERRQ(ierr); 260a8116848SStefano Zampini ierr = ISGetLocalSize(icol,&n);CHKERRQ(ierr); 261a8116848SStefano Zampini ierr = MatCreate(comm,newmat);CHKERRQ(ierr); 262a8116848SStefano Zampini ierr = MatSetType(*newmat,MATIS);CHKERRQ(ierr); 263a8116848SStefano Zampini ierr = MatSetSizes(*newmat,m,n,PETSC_DECIDE,PETSC_DECIDE);CHKERRQ(ierr); 264a8116848SStefano Zampini /* communicate irow to their owners in the layout */ 265a8116848SStefano Zampini ierr = ISGetIndices(irow,&idxs);CHKERRQ(ierr); 266f0ae7da4SStefano Zampini ierr = PetscLayoutMapLocal_Private(mat->rmap,m,idxs,&ll,&lidxs,&lgidxs);CHKERRQ(ierr); 267a8116848SStefano Zampini ierr = ISRestoreIndices(irow,&idxs);CHKERRQ(ierr); 268a8116848SStefano Zampini if (!matis->sf) { /* setup SF if not yet created and allocate rootdata and leafdata */ 269a8116848SStefano Zampini ierr = MatISComputeSF_Private(mat);CHKERRQ(ierr); 270a8116848SStefano Zampini } 271a8116848SStefano Zampini ierr = PetscMemzero(matis->sf_rootdata,matis->sf_nroots*sizeof(PetscInt));CHKERRQ(ierr); 272a8116848SStefano Zampini for (i=0;i<ll;i++) matis->sf_rootdata[lidxs[i]] = lgidxs[i]+1; 273a8116848SStefano Zampini ierr = PetscFree(lidxs);CHKERRQ(ierr); 274a8116848SStefano Zampini ierr = PetscFree(lgidxs);CHKERRQ(ierr); 275a8116848SStefano Zampini ierr = PetscSFBcastBegin(matis->sf,MPIU_INT,matis->sf_rootdata,matis->sf_leafdata);CHKERRQ(ierr); 276a8116848SStefano Zampini ierr = PetscSFBcastEnd(matis->sf,MPIU_INT,matis->sf_rootdata,matis->sf_leafdata);CHKERRQ(ierr); 277a8116848SStefano Zampini for (i=0,newloc=0;i<matis->sf_nleaves;i++) if (matis->sf_leafdata[i]) newloc++; 278a8116848SStefano Zampini ierr = PetscMalloc1(newloc,&newgidxs);CHKERRQ(ierr); 279a8116848SStefano Zampini ierr = PetscMalloc1(newloc,&lidxs);CHKERRQ(ierr); 280a8116848SStefano Zampini for (i=0,newloc=0;i<matis->sf_nleaves;i++) 281a8116848SStefano Zampini if (matis->sf_leafdata[i]) { 282a8116848SStefano Zampini lidxs[newloc] = i; 283a8116848SStefano Zampini newgidxs[newloc++] = matis->sf_leafdata[i]-1; 284a8116848SStefano Zampini } 285a8116848SStefano Zampini ierr = ISCreateGeneral(comm,newloc,newgidxs,PETSC_OWN_POINTER,&is);CHKERRQ(ierr); 286a8116848SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is,&rl2g);CHKERRQ(ierr); 287a8116848SStefano Zampini ierr = ISDestroy(&is);CHKERRQ(ierr); 288a8116848SStefano Zampini /* local is to extract local submatrix */ 289a8116848SStefano Zampini newmatis = (Mat_IS*)(*newmat)->data; 290a8116848SStefano Zampini ierr = ISCreateGeneral(comm,newloc,lidxs,PETSC_OWN_POINTER,&newmatis->getsub_ris);CHKERRQ(ierr); 291a8116848SStefano Zampini if (mat->congruentlayouts == -1) { /* first time we compare rows and cols layouts */ 292a8116848SStefano Zampini PetscBool cong; 293a8116848SStefano Zampini ierr = PetscLayoutCompare(mat->rmap,mat->cmap,&cong);CHKERRQ(ierr); 294a8116848SStefano Zampini if (cong) mat->congruentlayouts = 1; 295a8116848SStefano Zampini else mat->congruentlayouts = 0; 296a8116848SStefano Zampini } 297a8116848SStefano Zampini if (mat->congruentlayouts && irow == icol) { 298a8116848SStefano Zampini ierr = MatSetLocalToGlobalMapping(*newmat,rl2g,rl2g);CHKERRQ(ierr); 299a8116848SStefano Zampini ierr = PetscObjectReference((PetscObject)newmatis->getsub_ris);CHKERRQ(ierr); 300a8116848SStefano Zampini newmatis->getsub_cis = newmatis->getsub_ris; 301a8116848SStefano Zampini } else { 302a8116848SStefano Zampini ISLocalToGlobalMapping cl2g; 303a8116848SStefano Zampini 304a8116848SStefano Zampini /* communicate icol to their owners in the layout */ 305a8116848SStefano Zampini ierr = ISGetIndices(icol,&idxs);CHKERRQ(ierr); 306f0ae7da4SStefano Zampini ierr = PetscLayoutMapLocal_Private(mat->cmap,n,idxs,&ll,&lidxs,&lgidxs);CHKERRQ(ierr); 307a8116848SStefano Zampini ierr = ISRestoreIndices(icol,&idxs);CHKERRQ(ierr); 308a8116848SStefano Zampini ierr = PetscMemzero(matis->csf_rootdata,matis->csf_nroots*sizeof(PetscInt));CHKERRQ(ierr); 309a8116848SStefano Zampini for (i=0;i<ll;i++) matis->csf_rootdata[lidxs[i]] = lgidxs[i]+1; 310a8116848SStefano Zampini ierr = PetscFree(lidxs);CHKERRQ(ierr); 311a8116848SStefano Zampini ierr = PetscFree(lgidxs);CHKERRQ(ierr); 312a8116848SStefano Zampini ierr = PetscSFBcastBegin(matis->csf,MPIU_INT,matis->csf_rootdata,matis->csf_leafdata);CHKERRQ(ierr); 313a8116848SStefano Zampini ierr = PetscSFBcastEnd(matis->csf,MPIU_INT,matis->csf_rootdata,matis->csf_leafdata);CHKERRQ(ierr); 314a8116848SStefano Zampini for (i=0,newloc=0;i<matis->csf_nleaves;i++) if (matis->csf_leafdata[i]) newloc++; 315a8116848SStefano Zampini ierr = PetscMalloc1(newloc,&newgidxs);CHKERRQ(ierr); 316a8116848SStefano Zampini ierr = PetscMalloc1(newloc,&lidxs);CHKERRQ(ierr); 317a8116848SStefano Zampini for (i=0,newloc=0;i<matis->csf_nleaves;i++) 318a8116848SStefano Zampini if (matis->csf_leafdata[i]) { 319a8116848SStefano Zampini lidxs[newloc] = i; 320a8116848SStefano Zampini newgidxs[newloc++] = matis->csf_leafdata[i]-1; 321a8116848SStefano Zampini } 322a8116848SStefano Zampini ierr = ISCreateGeneral(comm,newloc,newgidxs,PETSC_OWN_POINTER,&is);CHKERRQ(ierr); 323a8116848SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is,&cl2g);CHKERRQ(ierr); 324a8116848SStefano Zampini ierr = ISDestroy(&is);CHKERRQ(ierr); 325a8116848SStefano Zampini /* local is to extract local submatrix */ 326a8116848SStefano Zampini ierr = ISCreateGeneral(comm,newloc,lidxs,PETSC_OWN_POINTER,&newmatis->getsub_cis);CHKERRQ(ierr); 327a8116848SStefano Zampini ierr = MatSetLocalToGlobalMapping(*newmat,rl2g,cl2g);CHKERRQ(ierr); 328a8116848SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&cl2g);CHKERRQ(ierr); 329a8116848SStefano Zampini } 330a8116848SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&rl2g);CHKERRQ(ierr); 331a8116848SStefano Zampini } else { 332a8116848SStefano Zampini ierr = MatISGetLocalMat(*newmat,&newlocmat);CHKERRQ(ierr); 333a8116848SStefano Zampini } 334a8116848SStefano Zampini ierr = MatISGetLocalMat(mat,&locmat);CHKERRQ(ierr); 335a8116848SStefano Zampini newmatis = (Mat_IS*)(*newmat)->data; 336a8116848SStefano Zampini ierr = MatGetSubMatrix(locmat,newmatis->getsub_ris,newmatis->getsub_cis,scall,&newlocmat);CHKERRQ(ierr); 337a8116848SStefano Zampini if (scall == MAT_INITIAL_MATRIX) { 338a8116848SStefano Zampini ierr = MatISSetLocalMat(*newmat,newlocmat);CHKERRQ(ierr); 339a8116848SStefano Zampini ierr = MatDestroy(&newlocmat);CHKERRQ(ierr); 340a8116848SStefano Zampini } 341a8116848SStefano Zampini ierr = MatAssemblyBegin(*newmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 342a8116848SStefano Zampini ierr = MatAssemblyEnd(*newmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 343a8116848SStefano Zampini PetscFunctionReturn(0); 344a8116848SStefano Zampini } 345a8116848SStefano Zampini 346a8116848SStefano Zampini #undef __FUNCT__ 3472b404112SStefano Zampini #define __FUNCT__ "MatCopy_IS" 348a8116848SStefano Zampini static PetscErrorCode MatCopy_IS(Mat A,Mat B,MatStructure str) 3492b404112SStefano Zampini { 3502b404112SStefano Zampini Mat_IS *a = (Mat_IS*)A->data,*b; 3512b404112SStefano Zampini PetscBool ismatis; 3522b404112SStefano Zampini PetscErrorCode ierr; 3532b404112SStefano Zampini 3542b404112SStefano Zampini PetscFunctionBegin; 3552b404112SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)B,MATIS,&ismatis);CHKERRQ(ierr); 3562b404112SStefano Zampini if (!ismatis) SETERRQ(PetscObjectComm((PetscObject)B),PETSC_ERR_SUP,"Need to be implemented"); 3572b404112SStefano Zampini b = (Mat_IS*)B->data; 3582b404112SStefano Zampini ierr = MatCopy(a->A,b->A,str);CHKERRQ(ierr); 3592b404112SStefano Zampini PetscFunctionReturn(0); 3602b404112SStefano Zampini } 3612b404112SStefano Zampini 3622b404112SStefano Zampini #undef __FUNCT__ 3636bd84002SStefano Zampini #define __FUNCT__ "MatMissingDiagonal_IS" 364a8116848SStefano Zampini static PetscErrorCode MatMissingDiagonal_IS(Mat A,PetscBool *missing,PetscInt *d) 3656bd84002SStefano Zampini { 366527b2640SStefano Zampini Vec v; 367527b2640SStefano Zampini const PetscScalar *array; 368527b2640SStefano Zampini PetscInt i,n; 3696bd84002SStefano Zampini PetscErrorCode ierr; 3706bd84002SStefano Zampini 3716bd84002SStefano Zampini PetscFunctionBegin; 372527b2640SStefano Zampini *missing = PETSC_FALSE; 373527b2640SStefano Zampini ierr = MatCreateVecs(A,NULL,&v);CHKERRQ(ierr); 374527b2640SStefano Zampini ierr = MatGetDiagonal(A,v);CHKERRQ(ierr); 375527b2640SStefano Zampini ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr); 376527b2640SStefano Zampini ierr = VecGetArrayRead(v,&array);CHKERRQ(ierr); 377527b2640SStefano Zampini for (i=0;i<n;i++) if (array[i] == 0.) break; 378527b2640SStefano Zampini ierr = VecRestoreArrayRead(v,&array);CHKERRQ(ierr); 379527b2640SStefano Zampini ierr = VecDestroy(&v);CHKERRQ(ierr); 380527b2640SStefano Zampini if (i != n) *missing = PETSC_TRUE; 381527b2640SStefano Zampini if (d) { 382527b2640SStefano Zampini *d = -1; 383527b2640SStefano Zampini if (*missing) { 384527b2640SStefano Zampini PetscInt rstart; 385527b2640SStefano Zampini ierr = MatGetOwnershipRange(A,&rstart,NULL);CHKERRQ(ierr); 386527b2640SStefano Zampini *d = i+rstart; 387527b2640SStefano Zampini } 388527b2640SStefano Zampini } 3896bd84002SStefano Zampini PetscFunctionReturn(0); 3906bd84002SStefano Zampini } 3916bd84002SStefano Zampini 3926bd84002SStefano Zampini #undef __FUNCT__ 39328f4e0baSStefano Zampini #define __FUNCT__ "MatISComputeSF_Private" 394a72627d2SStefano Zampini static PetscErrorCode MatISComputeSF_Private(Mat B) 39528f4e0baSStefano Zampini { 39628f4e0baSStefano Zampini Mat_IS *matis = (Mat_IS*)(B->data); 39728f4e0baSStefano Zampini const PetscInt *gidxs; 39828f4e0baSStefano Zampini PetscErrorCode ierr; 39928f4e0baSStefano Zampini 40028f4e0baSStefano Zampini PetscFunctionBegin; 40128f4e0baSStefano Zampini ierr = MatGetSize(matis->A,&matis->sf_nleaves,NULL);CHKERRQ(ierr); 40228f4e0baSStefano Zampini ierr = MatGetLocalSize(B,&matis->sf_nroots,NULL);CHKERRQ(ierr); 40328f4e0baSStefano Zampini ierr = PetscSFCreate(PetscObjectComm((PetscObject)B),&matis->sf);CHKERRQ(ierr); 4043bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(B->rmap->mapping,&gidxs);CHKERRQ(ierr); 40528f4e0baSStefano Zampini ierr = PetscSFSetGraphLayout(matis->sf,B->rmap,matis->sf_nleaves,NULL,PETSC_OWN_POINTER,gidxs);CHKERRQ(ierr); 4063bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(B->rmap->mapping,&gidxs);CHKERRQ(ierr); 40728f4e0baSStefano Zampini ierr = PetscMalloc2(matis->sf_nroots,&matis->sf_rootdata,matis->sf_nleaves,&matis->sf_leafdata);CHKERRQ(ierr); 408a8116848SStefano Zampini if (B->rmap->mapping != B->cmap->mapping) { /* setup SF for columns */ 409a8116848SStefano Zampini ierr = MatGetSize(matis->A,NULL,&matis->csf_nleaves);CHKERRQ(ierr); 410a8116848SStefano Zampini ierr = MatGetLocalSize(B,NULL,&matis->csf_nroots);CHKERRQ(ierr); 411a8116848SStefano Zampini ierr = PetscSFCreate(PetscObjectComm((PetscObject)B),&matis->csf);CHKERRQ(ierr); 412a8116848SStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(B->cmap->mapping,&gidxs);CHKERRQ(ierr); 413a8116848SStefano Zampini ierr = PetscSFSetGraphLayout(matis->csf,B->cmap,matis->csf_nleaves,NULL,PETSC_OWN_POINTER,gidxs);CHKERRQ(ierr); 414a8116848SStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(B->cmap->mapping,&gidxs);CHKERRQ(ierr); 415a8116848SStefano Zampini ierr = PetscMalloc2(matis->csf_nroots,&matis->csf_rootdata,matis->csf_nleaves,&matis->csf_leafdata);CHKERRQ(ierr); 416a8116848SStefano Zampini } else { 417a8116848SStefano Zampini matis->csf = matis->sf; 418a8116848SStefano Zampini matis->csf_nleaves = matis->sf_nleaves; 419a8116848SStefano Zampini matis->csf_nroots = matis->sf_nroots; 420a8116848SStefano Zampini matis->csf_leafdata = matis->sf_leafdata; 421a8116848SStefano Zampini matis->csf_rootdata = matis->sf_rootdata; 422a8116848SStefano Zampini } 42328f4e0baSStefano Zampini PetscFunctionReturn(0); 42428f4e0baSStefano Zampini } 4252e1947a5SStefano Zampini 4262e1947a5SStefano Zampini #undef __FUNCT__ 4272e1947a5SStefano Zampini #define __FUNCT__ "MatISSetPreallocation" 428eb82efa4SStefano Zampini /*@ 429a88811baSStefano Zampini MatISSetPreallocation - Preallocates memory for a MATIS parallel matrix. 430a88811baSStefano Zampini 431a88811baSStefano Zampini Collective on MPI_Comm 432a88811baSStefano Zampini 433a88811baSStefano Zampini Input Parameters: 434a88811baSStefano Zampini + B - the matrix 435a88811baSStefano Zampini . d_nz - number of nonzeros per row in DIAGONAL portion of local submatrix 436a88811baSStefano Zampini (same value is used for all local rows) 437a88811baSStefano Zampini . d_nnz - array containing the number of nonzeros in the various rows of the 438a88811baSStefano Zampini DIAGONAL portion of the local submatrix (possibly different for each row) 439a88811baSStefano Zampini or NULL, if d_nz is used to specify the nonzero structure. 440a88811baSStefano Zampini The size of this array is equal to the number of local rows, i.e 'm'. 441a88811baSStefano Zampini For matrices that will be factored, you must leave room for (and set) 442a88811baSStefano Zampini the diagonal entry even if it is zero. 443a88811baSStefano Zampini . o_nz - number of nonzeros per row in the OFF-DIAGONAL portion of local 444a88811baSStefano Zampini submatrix (same value is used for all local rows). 445a88811baSStefano Zampini - o_nnz - array containing the number of nonzeros in the various rows of the 446a88811baSStefano Zampini OFF-DIAGONAL portion of the local submatrix (possibly different for 447a88811baSStefano Zampini each row) or NULL, if o_nz is used to specify the nonzero 448a88811baSStefano Zampini structure. The size of this array is equal to the number 449a88811baSStefano Zampini of local rows, i.e 'm'. 450a88811baSStefano Zampini 451a88811baSStefano Zampini If the *_nnz parameter is given then the *_nz parameter is ignored 452a88811baSStefano Zampini 453a88811baSStefano Zampini Level: intermediate 454a88811baSStefano Zampini 455a88811baSStefano Zampini Notes: This function has the same interface as the MPIAIJ preallocation routine in order to simplify the transition 456a88811baSStefano Zampini from the asssembled format to the unassembled one. It overestimates the preallocation of MATIS local 457a88811baSStefano Zampini matrices; for exact preallocation, the user should set the preallocation directly on local matrix objects. 458a88811baSStefano Zampini 459a88811baSStefano Zampini .keywords: matrix 460a88811baSStefano Zampini 4613c212e90SHong Zhang .seealso: MatCreate(), MatCreateIS(), MatMPIAIJSetPreallocation(), MatISGetLocalMat(), MATIS 462a88811baSStefano Zampini @*/ 4632e1947a5SStefano Zampini PetscErrorCode MatISSetPreallocation(Mat B,PetscInt d_nz,const PetscInt d_nnz[],PetscInt o_nz,const PetscInt o_nnz[]) 4642e1947a5SStefano Zampini { 4652e1947a5SStefano Zampini PetscErrorCode ierr; 4662e1947a5SStefano Zampini 4672e1947a5SStefano Zampini PetscFunctionBegin; 4682e1947a5SStefano Zampini PetscValidHeaderSpecific(B,MAT_CLASSID,1); 4692e1947a5SStefano Zampini PetscValidType(B,1); 4702e1947a5SStefano Zampini ierr = PetscTryMethod(B,"MatISSetPreallocation_C",(Mat,PetscInt,const PetscInt[],PetscInt,const PetscInt[]),(B,d_nz,d_nnz,o_nz,o_nnz));CHKERRQ(ierr); 4712e1947a5SStefano Zampini PetscFunctionReturn(0); 4722e1947a5SStefano Zampini } 4732e1947a5SStefano Zampini 4742e1947a5SStefano Zampini #undef __FUNCT__ 4752e1947a5SStefano Zampini #define __FUNCT__ "MatISSetPreallocation_IS" 4767230de76SStefano Zampini static PetscErrorCode MatISSetPreallocation_IS(Mat B,PetscInt d_nz,const PetscInt d_nnz[],PetscInt o_nz,const PetscInt o_nnz[]) 4772e1947a5SStefano Zampini { 4782e1947a5SStefano Zampini Mat_IS *matis = (Mat_IS*)(B->data); 47928f4e0baSStefano Zampini PetscInt bs,i,nlocalcols; 4802e1947a5SStefano Zampini PetscErrorCode ierr; 4812e1947a5SStefano Zampini 4822e1947a5SStefano Zampini PetscFunctionBegin; 4836c4ed002SBarry Smith if (!matis->A) SETERRQ(PetscObjectComm((PetscObject)B),PETSC_ERR_SUP,"You should first call MatSetLocalToGlobalMapping"); 48428f4e0baSStefano Zampini if (!matis->sf) { /* setup SF if not yet created and allocate rootdata and leafdata */ 48528f4e0baSStefano Zampini ierr = MatISComputeSF_Private(B);CHKERRQ(ierr); 48628f4e0baSStefano Zampini } 4872e1947a5SStefano Zampini if (!d_nnz) { 48828f4e0baSStefano Zampini for (i=0;i<matis->sf_nroots;i++) matis->sf_rootdata[i] = d_nz; 4892e1947a5SStefano Zampini } else { 49028f4e0baSStefano Zampini for (i=0;i<matis->sf_nroots;i++) matis->sf_rootdata[i] = d_nnz[i]; 4912e1947a5SStefano Zampini } 4922e1947a5SStefano Zampini if (!o_nnz) { 49328f4e0baSStefano Zampini for (i=0;i<matis->sf_nroots;i++) matis->sf_rootdata[i] += o_nz; 4942e1947a5SStefano Zampini } else { 49528f4e0baSStefano Zampini for (i=0;i<matis->sf_nroots;i++) matis->sf_rootdata[i] += o_nnz[i]; 4962e1947a5SStefano Zampini } 49728f4e0baSStefano Zampini ierr = PetscSFBcastBegin(matis->sf,MPIU_INT,matis->sf_rootdata,matis->sf_leafdata);CHKERRQ(ierr); 49828f4e0baSStefano Zampini ierr = MatGetSize(matis->A,NULL,&nlocalcols);CHKERRQ(ierr); 49928f4e0baSStefano Zampini ierr = MatGetBlockSize(matis->A,&bs);CHKERRQ(ierr); 50028f4e0baSStefano Zampini ierr = PetscSFBcastEnd(matis->sf,MPIU_INT,matis->sf_rootdata,matis->sf_leafdata);CHKERRQ(ierr); 50128f4e0baSStefano Zampini for (i=0;i<matis->sf_nleaves;i++) { 50228f4e0baSStefano Zampini matis->sf_leafdata[i] = PetscMin(matis->sf_leafdata[i],nlocalcols); 5032e1947a5SStefano Zampini } 50428f4e0baSStefano Zampini ierr = MatSeqAIJSetPreallocation(matis->A,0,matis->sf_leafdata);CHKERRQ(ierr); 50528f4e0baSStefano Zampini for (i=0;i<matis->sf_nleaves/bs;i++) { 50628f4e0baSStefano Zampini matis->sf_leafdata[i] = matis->sf_leafdata[i*bs]/bs; 5072e1947a5SStefano Zampini } 50828f4e0baSStefano Zampini ierr = MatSeqBAIJSetPreallocation(matis->A,bs,0,matis->sf_leafdata);CHKERRQ(ierr); 50928f4e0baSStefano Zampini for (i=0;i<matis->sf_nleaves/bs;i++) { 51028f4e0baSStefano Zampini matis->sf_leafdata[i] = matis->sf_leafdata[i]-i; 5112e1947a5SStefano Zampini } 51228f4e0baSStefano Zampini ierr = MatSeqSBAIJSetPreallocation(matis->A,bs,0,matis->sf_leafdata);CHKERRQ(ierr); 5132e1947a5SStefano Zampini PetscFunctionReturn(0); 5142e1947a5SStefano Zampini } 515b4319ba4SBarry Smith 516b4319ba4SBarry Smith #undef __FUNCT__ 5173927de2eSStefano Zampini #define __FUNCT__ "MatISSetMPIXAIJPreallocation_Private" 5183927de2eSStefano Zampini PETSC_EXTERN PetscErrorCode MatISSetMPIXAIJPreallocation_Private(Mat A, Mat B, PetscBool maxreduce) 5193927de2eSStefano Zampini { 5203927de2eSStefano Zampini Mat_IS *matis = (Mat_IS*)(A->data); 5213927de2eSStefano Zampini PetscInt *my_dnz,*my_onz,*dnz,*onz,*mat_ranges,*row_ownership; 522ecf5a873SStefano Zampini const PetscInt *global_indices_r,*global_indices_c; 5233927de2eSStefano Zampini PetscInt i,j,bs,rows,cols; 5243927de2eSStefano Zampini PetscInt lrows,lcols; 5253927de2eSStefano Zampini PetscInt local_rows,local_cols; 5263927de2eSStefano Zampini PetscMPIInt nsubdomains; 5273927de2eSStefano Zampini PetscBool isdense,issbaij; 5283927de2eSStefano Zampini PetscErrorCode ierr; 5293927de2eSStefano Zampini 5303927de2eSStefano Zampini PetscFunctionBegin; 5313927de2eSStefano Zampini ierr = MPI_Comm_size(PetscObjectComm((PetscObject)A),&nsubdomains);CHKERRQ(ierr); 5323927de2eSStefano Zampini ierr = MatGetSize(A,&rows,&cols);CHKERRQ(ierr); 5333927de2eSStefano Zampini ierr = MatGetBlockSize(A,&bs);CHKERRQ(ierr); 5343927de2eSStefano Zampini ierr = MatGetSize(matis->A,&local_rows,&local_cols);CHKERRQ(ierr); 5353927de2eSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)matis->A,MATSEQDENSE,&isdense);CHKERRQ(ierr); 5363927de2eSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)matis->A,MATSEQSBAIJ,&issbaij);CHKERRQ(ierr); 537ecf5a873SStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(A->rmap->mapping,&global_indices_r);CHKERRQ(ierr); 538ecf5a873SStefano Zampini if (A->rmap->mapping != A->cmap->mapping) { 5397230de76SStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(A->cmap->mapping,&global_indices_c);CHKERRQ(ierr); 540ecf5a873SStefano Zampini } else { 541ecf5a873SStefano Zampini global_indices_c = global_indices_r; 542ecf5a873SStefano Zampini } 543ecf5a873SStefano Zampini 5443927de2eSStefano Zampini if (issbaij) { 5453927de2eSStefano Zampini ierr = MatGetRowUpperTriangular(matis->A);CHKERRQ(ierr); 5463927de2eSStefano Zampini } 5473927de2eSStefano Zampini /* 548ecf5a873SStefano Zampini An SF reduce is needed to sum up properly on shared rows. 5493927de2eSStefano Zampini Note that generally preallocation is not exact, since it overestimates nonzeros 5503927de2eSStefano Zampini */ 5513927de2eSStefano Zampini if (!matis->sf) { /* setup SF if not yet created and allocate rootdata and leafdata */ 5523927de2eSStefano Zampini ierr = MatISComputeSF_Private(A);CHKERRQ(ierr); 5533927de2eSStefano Zampini } 5543927de2eSStefano Zampini ierr = MatGetLocalSize(A,&lrows,&lcols);CHKERRQ(ierr); 5553927de2eSStefano Zampini ierr = MatPreallocateInitialize(PetscObjectComm((PetscObject)A),lrows,lcols,dnz,onz);CHKERRQ(ierr); 5563927de2eSStefano Zampini /* All processes need to compute entire row ownership */ 5573927de2eSStefano Zampini ierr = PetscMalloc1(rows,&row_ownership);CHKERRQ(ierr); 5583927de2eSStefano Zampini ierr = MatGetOwnershipRanges(A,(const PetscInt**)&mat_ranges);CHKERRQ(ierr); 5593927de2eSStefano Zampini for (i=0;i<nsubdomains;i++) { 5603927de2eSStefano Zampini for (j=mat_ranges[i];j<mat_ranges[i+1];j++) { 5613927de2eSStefano Zampini row_ownership[j] = i; 5623927de2eSStefano Zampini } 5633927de2eSStefano Zampini } 5647230de76SStefano Zampini ierr = MatGetOwnershipRangesColumn(A,(const PetscInt**)&mat_ranges);CHKERRQ(ierr); 5653927de2eSStefano Zampini 5663927de2eSStefano Zampini /* 5673927de2eSStefano Zampini my_dnz and my_onz contains exact contribution to preallocation from each local mat 5683927de2eSStefano Zampini then, they will be summed up properly. This way, preallocation is always sufficient 5693927de2eSStefano Zampini */ 5703927de2eSStefano Zampini ierr = PetscCalloc2(local_rows,&my_dnz,local_rows,&my_onz);CHKERRQ(ierr); 5713927de2eSStefano Zampini /* preallocation as a MATAIJ */ 5723927de2eSStefano Zampini if (isdense) { /* special case for dense local matrices */ 5733927de2eSStefano Zampini for (i=0;i<local_rows;i++) { 574ecf5a873SStefano Zampini PetscInt index_row = global_indices_r[i]; 5753927de2eSStefano Zampini for (j=i;j<local_rows;j++) { 5763927de2eSStefano Zampini PetscInt owner = row_ownership[index_row]; 577ecf5a873SStefano Zampini PetscInt index_col = global_indices_c[j]; 5783927de2eSStefano Zampini if (index_col > mat_ranges[owner]-1 && index_col < mat_ranges[owner+1] ) { /* diag block */ 5793927de2eSStefano Zampini my_dnz[i] += 1; 5803927de2eSStefano Zampini } else { /* offdiag block */ 5813927de2eSStefano Zampini my_onz[i] += 1; 5823927de2eSStefano Zampini } 5833927de2eSStefano Zampini /* same as before, interchanging rows and cols */ 5843927de2eSStefano Zampini if (i != j) { 5853927de2eSStefano Zampini owner = row_ownership[index_col]; 5863927de2eSStefano Zampini if (index_row > mat_ranges[owner]-1 && index_row < mat_ranges[owner+1] ) { 5873927de2eSStefano Zampini my_dnz[j] += 1; 5883927de2eSStefano Zampini } else { 5893927de2eSStefano Zampini my_onz[j] += 1; 5903927de2eSStefano Zampini } 5913927de2eSStefano Zampini } 5923927de2eSStefano Zampini } 5933927de2eSStefano Zampini } 594bb1015c3SStefano Zampini } else if (matis->A->ops->getrowij) { 595bb1015c3SStefano Zampini const PetscInt *ii,*jj,*jptr; 596bb1015c3SStefano Zampini PetscBool done; 597bb1015c3SStefano Zampini ierr = MatGetRowIJ(matis->A,0,PETSC_FALSE,PETSC_FALSE,&local_rows,&ii,&jj,&done);CHKERRQ(ierr); 598bb1015c3SStefano Zampini if (!done) SETERRQ1(PetscObjectComm((PetscObject)(matis->A)),PETSC_ERR_PLIB,"Error in MatGetRowIJ called from %s\n",__FUNCT__); 599bb1015c3SStefano Zampini jptr = jj; 600bb1015c3SStefano Zampini for (i=0;i<local_rows;i++) { 601bb1015c3SStefano Zampini PetscInt index_row = global_indices_r[i]; 602bb1015c3SStefano Zampini for (j=0;j<ii[i+1]-ii[i];j++,jptr++) { 603bb1015c3SStefano Zampini PetscInt owner = row_ownership[index_row]; 604bb1015c3SStefano Zampini PetscInt index_col = global_indices_c[*jptr]; 605bb1015c3SStefano Zampini if (index_col > mat_ranges[owner]-1 && index_col < mat_ranges[owner+1] ) { /* diag block */ 606bb1015c3SStefano Zampini my_dnz[i] += 1; 607bb1015c3SStefano Zampini } else { /* offdiag block */ 608bb1015c3SStefano Zampini my_onz[i] += 1; 609bb1015c3SStefano Zampini } 610bb1015c3SStefano Zampini /* same as before, interchanging rows and cols */ 611bb1015c3SStefano Zampini if (issbaij && index_col != index_row) { 612bb1015c3SStefano Zampini owner = row_ownership[index_col]; 613bb1015c3SStefano Zampini if (index_row > mat_ranges[owner]-1 && index_row < mat_ranges[owner+1] ) { 614bb1015c3SStefano Zampini my_dnz[*jptr] += 1; 615bb1015c3SStefano Zampini } else { 616bb1015c3SStefano Zampini my_onz[*jptr] += 1; 617bb1015c3SStefano Zampini } 618bb1015c3SStefano Zampini } 619bb1015c3SStefano Zampini } 620bb1015c3SStefano Zampini } 621bb1015c3SStefano Zampini ierr = MatRestoreRowIJ(matis->A,0,PETSC_FALSE,PETSC_FALSE,&local_rows,&ii,&jj,&done);CHKERRQ(ierr); 622bb1015c3SStefano Zampini if (!done) SETERRQ1(PetscObjectComm((PetscObject)(matis->A)),PETSC_ERR_PLIB,"Error in MatRestoreRowIJ called from %s\n",__FUNCT__); 623bb1015c3SStefano Zampini } else { /* loop over rows and use MatGetRow */ 6243927de2eSStefano Zampini for (i=0;i<local_rows;i++) { 6253927de2eSStefano Zampini const PetscInt *cols; 626ecf5a873SStefano Zampini PetscInt ncols,index_row = global_indices_r[i]; 6273927de2eSStefano Zampini ierr = MatGetRow(matis->A,i,&ncols,&cols,NULL);CHKERRQ(ierr); 6283927de2eSStefano Zampini for (j=0;j<ncols;j++) { 6293927de2eSStefano Zampini PetscInt owner = row_ownership[index_row]; 630ecf5a873SStefano Zampini PetscInt index_col = global_indices_c[cols[j]]; 6313927de2eSStefano Zampini if (index_col > mat_ranges[owner]-1 && index_col < mat_ranges[owner+1] ) { /* diag block */ 6323927de2eSStefano Zampini my_dnz[i] += 1; 6333927de2eSStefano Zampini } else { /* offdiag block */ 6343927de2eSStefano Zampini my_onz[i] += 1; 6353927de2eSStefano Zampini } 6363927de2eSStefano Zampini /* same as before, interchanging rows and cols */ 637d9a9e74cSStefano Zampini if (issbaij && index_col != index_row) { 6383927de2eSStefano Zampini owner = row_ownership[index_col]; 6393927de2eSStefano Zampini if (index_row > mat_ranges[owner]-1 && index_row < mat_ranges[owner+1] ) { 640d9a9e74cSStefano Zampini my_dnz[cols[j]] += 1; 6413927de2eSStefano Zampini } else { 642d9a9e74cSStefano Zampini my_onz[cols[j]] += 1; 6433927de2eSStefano Zampini } 6443927de2eSStefano Zampini } 6453927de2eSStefano Zampini } 6463927de2eSStefano Zampini ierr = MatRestoreRow(matis->A,i,&ncols,&cols,NULL);CHKERRQ(ierr); 6473927de2eSStefano Zampini } 6483927de2eSStefano Zampini } 649ecf5a873SStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(A->rmap->mapping,&global_indices_r);CHKERRQ(ierr); 650ecf5a873SStefano Zampini if (global_indices_c != global_indices_r) { 6517230de76SStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(A->cmap->mapping,&global_indices_c);CHKERRQ(ierr); 652ecf5a873SStefano Zampini } 6533927de2eSStefano Zampini ierr = PetscFree(row_ownership);CHKERRQ(ierr); 654ecf5a873SStefano Zampini 655ecf5a873SStefano Zampini /* Reduce my_dnz and my_onz */ 6563927de2eSStefano Zampini if (maxreduce) { 6573927de2eSStefano Zampini ierr = PetscSFReduceBegin(matis->sf,MPIU_INT,my_dnz,dnz,MPI_MAX);CHKERRQ(ierr); 6583927de2eSStefano Zampini ierr = PetscSFReduceBegin(matis->sf,MPIU_INT,my_onz,onz,MPI_MAX);CHKERRQ(ierr); 659bb1015c3SStefano Zampini ierr = PetscSFReduceEnd(matis->sf,MPIU_INT,my_dnz,dnz,MPI_MAX);CHKERRQ(ierr); 6603927de2eSStefano Zampini ierr = PetscSFReduceEnd(matis->sf,MPIU_INT,my_onz,onz,MPI_MAX);CHKERRQ(ierr); 6613927de2eSStefano Zampini } else { 6623927de2eSStefano Zampini ierr = PetscSFReduceBegin(matis->sf,MPIU_INT,my_dnz,dnz,MPI_SUM);CHKERRQ(ierr); 6633927de2eSStefano Zampini ierr = PetscSFReduceBegin(matis->sf,MPIU_INT,my_onz,onz,MPI_SUM);CHKERRQ(ierr); 664bb1015c3SStefano Zampini ierr = PetscSFReduceEnd(matis->sf,MPIU_INT,my_dnz,dnz,MPI_SUM);CHKERRQ(ierr); 6653927de2eSStefano Zampini ierr = PetscSFReduceEnd(matis->sf,MPIU_INT,my_onz,onz,MPI_SUM);CHKERRQ(ierr); 6663927de2eSStefano Zampini } 6673927de2eSStefano Zampini ierr = PetscFree2(my_dnz,my_onz);CHKERRQ(ierr); 6683927de2eSStefano Zampini 6693927de2eSStefano Zampini /* Resize preallocation if overestimated */ 6703927de2eSStefano Zampini for (i=0;i<lrows;i++) { 6713927de2eSStefano Zampini dnz[i] = PetscMin(dnz[i],lcols); 6723927de2eSStefano Zampini onz[i] = PetscMin(onz[i],cols-lcols); 6733927de2eSStefano Zampini } 6743927de2eSStefano Zampini /* set preallocation */ 6753927de2eSStefano Zampini ierr = MatMPIAIJSetPreallocation(B,0,dnz,0,onz);CHKERRQ(ierr); 6763927de2eSStefano Zampini for (i=0;i<lrows/bs;i++) { 6773927de2eSStefano Zampini dnz[i] = dnz[i*bs]/bs; 6783927de2eSStefano Zampini onz[i] = onz[i*bs]/bs; 6793927de2eSStefano Zampini } 6803927de2eSStefano Zampini ierr = MatMPIBAIJSetPreallocation(B,bs,0,dnz,0,onz);CHKERRQ(ierr); 6813927de2eSStefano Zampini ierr = MatMPISBAIJSetPreallocation(B,bs,0,dnz,0,onz);CHKERRQ(ierr); 6823927de2eSStefano Zampini ierr = MatPreallocateFinalize(dnz,onz);CHKERRQ(ierr); 6833927de2eSStefano Zampini if (issbaij) { 6843927de2eSStefano Zampini ierr = MatRestoreRowUpperTriangular(matis->A);CHKERRQ(ierr); 6853927de2eSStefano Zampini } 6863927de2eSStefano Zampini PetscFunctionReturn(0); 6873927de2eSStefano Zampini } 6883927de2eSStefano Zampini 6893927de2eSStefano Zampini #undef __FUNCT__ 690b7ce53b6SStefano Zampini #define __FUNCT__ "MatISGetMPIXAIJ_IS" 6917230de76SStefano Zampini static PetscErrorCode MatISGetMPIXAIJ_IS(Mat mat, MatReuse reuse, Mat *M) 692b7ce53b6SStefano Zampini { 693b7ce53b6SStefano Zampini Mat_IS *matis = (Mat_IS*)(mat->data); 694d9a9e74cSStefano Zampini Mat local_mat; 695b7ce53b6SStefano Zampini /* info on mat */ 6963cfa4ea4SStefano Zampini PetscInt bs,rows,cols,lrows,lcols; 697b7ce53b6SStefano Zampini PetscInt local_rows,local_cols; 698686e3a49SStefano Zampini PetscBool isdense,issbaij,isseqaij; 6997c03b4e8SStefano Zampini PetscMPIInt nsubdomains; 700b7ce53b6SStefano Zampini /* values insertion */ 701b7ce53b6SStefano Zampini PetscScalar *array; 702b7ce53b6SStefano Zampini /* work */ 703b7ce53b6SStefano Zampini PetscErrorCode ierr; 704b7ce53b6SStefano Zampini 705b7ce53b6SStefano Zampini PetscFunctionBegin; 706b7ce53b6SStefano Zampini /* get info from mat */ 7077c03b4e8SStefano Zampini ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&nsubdomains);CHKERRQ(ierr); 7087c03b4e8SStefano Zampini if (nsubdomains == 1) { 7097c03b4e8SStefano Zampini if (reuse == MAT_INITIAL_MATRIX) { 7107c03b4e8SStefano Zampini ierr = MatDuplicate(matis->A,MAT_COPY_VALUES,&(*M));CHKERRQ(ierr); 7117c03b4e8SStefano Zampini } else { 7127c03b4e8SStefano Zampini ierr = MatCopy(matis->A,*M,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 7137c03b4e8SStefano Zampini } 7147c03b4e8SStefano Zampini PetscFunctionReturn(0); 7157c03b4e8SStefano Zampini } 716b7ce53b6SStefano Zampini ierr = MatGetSize(mat,&rows,&cols);CHKERRQ(ierr); 717b7ce53b6SStefano Zampini ierr = MatGetBlockSize(mat,&bs);CHKERRQ(ierr); 7183cfa4ea4SStefano Zampini ierr = MatGetLocalSize(mat,&lrows,&lcols);CHKERRQ(ierr); 719b7ce53b6SStefano Zampini ierr = MatGetSize(matis->A,&local_rows,&local_cols);CHKERRQ(ierr); 720b7ce53b6SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)matis->A,MATSEQDENSE,&isdense);CHKERRQ(ierr); 721686e3a49SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)matis->A,MATSEQAIJ,&isseqaij);CHKERRQ(ierr); 722b7ce53b6SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)matis->A,MATSEQSBAIJ,&issbaij);CHKERRQ(ierr); 723b7ce53b6SStefano Zampini 724b7ce53b6SStefano Zampini if (reuse == MAT_INITIAL_MATRIX) { 725b7ce53b6SStefano Zampini MatType new_mat_type; 7263927de2eSStefano Zampini PetscBool issbaij_red; 727b7ce53b6SStefano Zampini 728b7ce53b6SStefano Zampini /* determining new matrix type */ 729b2566f29SBarry Smith ierr = MPIU_Allreduce(&issbaij,&issbaij_red,1,MPIU_BOOL,MPI_LAND,PetscObjectComm((PetscObject)mat));CHKERRQ(ierr); 730b7ce53b6SStefano Zampini if (issbaij_red) { 731b7ce53b6SStefano Zampini new_mat_type = MATSBAIJ; 732b7ce53b6SStefano Zampini } else { 733b7ce53b6SStefano Zampini if (bs>1) { 734b7ce53b6SStefano Zampini new_mat_type = MATBAIJ; 735b7ce53b6SStefano Zampini } else { 736b7ce53b6SStefano Zampini new_mat_type = MATAIJ; 737b7ce53b6SStefano Zampini } 738b7ce53b6SStefano Zampini } 739b7ce53b6SStefano Zampini 7403927de2eSStefano Zampini ierr = MatCreate(PetscObjectComm((PetscObject)mat),M);CHKERRQ(ierr); 7413cfa4ea4SStefano Zampini ierr = MatSetSizes(*M,lrows,lcols,rows,cols);CHKERRQ(ierr); 7423927de2eSStefano Zampini ierr = MatSetBlockSize(*M,bs);CHKERRQ(ierr); 7433927de2eSStefano Zampini ierr = MatSetType(*M,new_mat_type);CHKERRQ(ierr); 7443927de2eSStefano Zampini ierr = MatISSetMPIXAIJPreallocation_Private(mat,*M,PETSC_FALSE);CHKERRQ(ierr); 745b7ce53b6SStefano Zampini } else { 7463cfa4ea4SStefano Zampini PetscInt mbs,mrows,mcols,mlrows,mlcols; 747b7ce53b6SStefano Zampini /* some checks */ 748b7ce53b6SStefano Zampini ierr = MatGetBlockSize(*M,&mbs);CHKERRQ(ierr); 749b7ce53b6SStefano Zampini ierr = MatGetSize(*M,&mrows,&mcols);CHKERRQ(ierr); 7503cfa4ea4SStefano Zampini ierr = MatGetLocalSize(*M,&mlrows,&mlcols);CHKERRQ(ierr); 7516c4ed002SBarry Smith if (mrows != rows) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot reuse matrix. Wrong number of rows (%d != %d)",rows,mrows); 7526c4ed002SBarry Smith if (mcols != cols) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot reuse matrix. Wrong number of cols (%d != %d)",cols,mcols); 7536c4ed002SBarry Smith if (mlrows != lrows) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot reuse matrix. Wrong number of local rows (%d != %d)",lrows,mlrows); 7546c4ed002SBarry Smith if (mlcols != lcols) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot reuse matrix. Wrong number of local cols (%d != %d)",lcols,mlcols); 7556c4ed002SBarry Smith if (mbs != bs) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot reuse matrix. Wrong block size (%d != %d)",bs,mbs); 756b7ce53b6SStefano Zampini ierr = MatZeroEntries(*M);CHKERRQ(ierr); 757b7ce53b6SStefano Zampini } 758d9a9e74cSStefano Zampini 759d9a9e74cSStefano Zampini if (issbaij) { 760d9a9e74cSStefano Zampini ierr = MatConvert(matis->A,MATSEQBAIJ,MAT_INITIAL_MATRIX,&local_mat);CHKERRQ(ierr); 761d9a9e74cSStefano Zampini } else { 762d9a9e74cSStefano Zampini ierr = PetscObjectReference((PetscObject)matis->A);CHKERRQ(ierr); 763d9a9e74cSStefano Zampini local_mat = matis->A; 764d9a9e74cSStefano Zampini } 765686e3a49SStefano Zampini 766b7ce53b6SStefano Zampini /* Set values */ 767ecf5a873SStefano Zampini ierr = MatSetLocalToGlobalMapping(*M,mat->rmap->mapping,mat->cmap->mapping);CHKERRQ(ierr); 768b7ce53b6SStefano Zampini if (isdense) { /* special case for dense local matrices */ 769ecf5a873SStefano Zampini PetscInt i,*dummy_rows,*dummy_cols; 770ecf5a873SStefano Zampini 771ecf5a873SStefano Zampini if (local_rows != local_cols) { 772ecf5a873SStefano Zampini ierr = PetscMalloc2(local_rows,&dummy_rows,local_cols,&dummy_cols);CHKERRQ(ierr); 773ecf5a873SStefano Zampini for (i=0;i<local_rows;i++) dummy_rows[i] = i; 774ecf5a873SStefano Zampini for (i=0;i<local_cols;i++) dummy_cols[i] = i; 775ecf5a873SStefano Zampini } else { 776ecf5a873SStefano Zampini ierr = PetscMalloc1(local_rows,&dummy_rows);CHKERRQ(ierr); 777ecf5a873SStefano Zampini for (i=0;i<local_rows;i++) dummy_rows[i] = i; 778ecf5a873SStefano Zampini dummy_cols = dummy_rows; 779ecf5a873SStefano Zampini } 780b7ce53b6SStefano Zampini ierr = MatSetOption(*M,MAT_ROW_ORIENTED,PETSC_FALSE);CHKERRQ(ierr); 781d9a9e74cSStefano Zampini ierr = MatDenseGetArray(local_mat,&array);CHKERRQ(ierr); 782ecf5a873SStefano Zampini ierr = MatSetValuesLocal(*M,local_rows,dummy_rows,local_cols,dummy_cols,array,ADD_VALUES);CHKERRQ(ierr); 783d9a9e74cSStefano Zampini ierr = MatDenseRestoreArray(local_mat,&array);CHKERRQ(ierr); 784ecf5a873SStefano Zampini if (dummy_rows != dummy_cols) { 785ecf5a873SStefano Zampini ierr = PetscFree2(dummy_rows,dummy_cols);CHKERRQ(ierr); 786ecf5a873SStefano Zampini } else { 787ecf5a873SStefano Zampini ierr = PetscFree(dummy_rows);CHKERRQ(ierr); 788ecf5a873SStefano Zampini } 789686e3a49SStefano Zampini } else if (isseqaij) { 790ecf5a873SStefano Zampini PetscInt i,nvtxs,*xadj,*adjncy; 791686e3a49SStefano Zampini PetscBool done; 792686e3a49SStefano Zampini 793d9a9e74cSStefano Zampini ierr = MatGetRowIJ(local_mat,0,PETSC_FALSE,PETSC_FALSE,&nvtxs,(const PetscInt**)&xadj,(const PetscInt**)&adjncy,&done);CHKERRQ(ierr); 794bb1015c3SStefano Zampini if (!done) SETERRQ1(PetscObjectComm((PetscObject)local_mat),PETSC_ERR_PLIB,"Error in MatGetRowIJ called from %s\n",__FUNCT__); 795d9a9e74cSStefano Zampini ierr = MatSeqAIJGetArray(local_mat,&array);CHKERRQ(ierr); 796686e3a49SStefano Zampini for (i=0;i<nvtxs;i++) { 797ecf5a873SStefano Zampini ierr = MatSetValuesLocal(*M,1,&i,xadj[i+1]-xadj[i],adjncy+xadj[i],array+xadj[i],ADD_VALUES);CHKERRQ(ierr); 798686e3a49SStefano Zampini } 799d9a9e74cSStefano Zampini ierr = MatRestoreRowIJ(local_mat,0,PETSC_FALSE,PETSC_FALSE,&nvtxs,(const PetscInt**)&xadj,(const PetscInt**)&adjncy,&done);CHKERRQ(ierr); 800bb1015c3SStefano Zampini if (!done) SETERRQ1(PetscObjectComm((PetscObject)local_mat),PETSC_ERR_PLIB,"Error in MatRestoreRowIJ called from %s\n",__FUNCT__); 801d9a9e74cSStefano Zampini ierr = MatSeqAIJRestoreArray(local_mat,&array);CHKERRQ(ierr); 802686e3a49SStefano Zampini } else { /* very basic values insertion for all other matrix types */ 803ecf5a873SStefano Zampini PetscInt i; 804c0962df8SStefano Zampini 805686e3a49SStefano Zampini for (i=0;i<local_rows;i++) { 806686e3a49SStefano Zampini PetscInt j; 807ecf5a873SStefano Zampini const PetscInt *local_indices_cols; 808686e3a49SStefano Zampini 809ecf5a873SStefano Zampini ierr = MatGetRow(local_mat,i,&j,&local_indices_cols,(const PetscScalar**)&array);CHKERRQ(ierr); 810ecf5a873SStefano Zampini ierr = MatSetValuesLocal(*M,1,&i,j,local_indices_cols,array,ADD_VALUES);CHKERRQ(ierr); 811ecf5a873SStefano Zampini ierr = MatRestoreRow(local_mat,i,&j,&local_indices_cols,(const PetscScalar**)&array);CHKERRQ(ierr); 812686e3a49SStefano Zampini } 813b7ce53b6SStefano Zampini } 814b7ce53b6SStefano Zampini ierr = MatAssemblyBegin(*M,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 815d9a9e74cSStefano Zampini ierr = MatDestroy(&local_mat);CHKERRQ(ierr); 816b7ce53b6SStefano Zampini ierr = MatAssemblyEnd(*M,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 817b7ce53b6SStefano Zampini if (isdense) { 818b7ce53b6SStefano Zampini ierr = MatSetOption(*M,MAT_ROW_ORIENTED,PETSC_TRUE);CHKERRQ(ierr); 819b7ce53b6SStefano Zampini } 820b7ce53b6SStefano Zampini PetscFunctionReturn(0); 821b7ce53b6SStefano Zampini } 822b7ce53b6SStefano Zampini 823b7ce53b6SStefano Zampini #undef __FUNCT__ 824b7ce53b6SStefano Zampini #define __FUNCT__ "MatISGetMPIXAIJ" 825b7ce53b6SStefano Zampini /*@ 826b7ce53b6SStefano Zampini MatISGetMPIXAIJ - Converts MATIS matrix into a parallel AIJ format 827b7ce53b6SStefano Zampini 828b7ce53b6SStefano Zampini Input Parameter: 829b7ce53b6SStefano Zampini . mat - the matrix (should be of type MATIS) 830b7ce53b6SStefano Zampini . reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 831b7ce53b6SStefano Zampini 832b7ce53b6SStefano Zampini Output Parameter: 833b7ce53b6SStefano Zampini . newmat - the matrix in AIJ format 834b7ce53b6SStefano Zampini 835b7ce53b6SStefano Zampini Level: developer 836b7ce53b6SStefano Zampini 837eb82efa4SStefano Zampini Notes: mat and *newmat cannot be the same object when MAT_REUSE_MATRIX is requested. 838b7ce53b6SStefano Zampini 839b7ce53b6SStefano Zampini .seealso: MATIS 840b7ce53b6SStefano Zampini @*/ 841b7ce53b6SStefano Zampini PetscErrorCode MatISGetMPIXAIJ(Mat mat, MatReuse reuse, Mat *newmat) 842b7ce53b6SStefano Zampini { 843b7ce53b6SStefano Zampini PetscErrorCode ierr; 844b7ce53b6SStefano Zampini 845b7ce53b6SStefano Zampini PetscFunctionBegin; 846b7ce53b6SStefano Zampini PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 847b7ce53b6SStefano Zampini PetscValidLogicalCollectiveEnum(mat,reuse,2); 848b7ce53b6SStefano Zampini PetscValidPointer(newmat,3); 849b7ce53b6SStefano Zampini if (reuse != MAT_INITIAL_MATRIX) { 850b7ce53b6SStefano Zampini PetscValidHeaderSpecific(*newmat,MAT_CLASSID,3); 851b7ce53b6SStefano Zampini PetscCheckSameComm(mat,1,*newmat,3); 8526c4ed002SBarry Smith if (mat == *newmat) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot reuse the same matrix"); 853b7ce53b6SStefano Zampini } 854b7ce53b6SStefano Zampini ierr = PetscUseMethod(mat,"MatISGetMPIXAIJ_C",(Mat,MatReuse,Mat*),(mat,reuse,newmat));CHKERRQ(ierr); 855b7ce53b6SStefano Zampini PetscFunctionReturn(0); 856b7ce53b6SStefano Zampini } 857b7ce53b6SStefano Zampini 858b7ce53b6SStefano Zampini #undef __FUNCT__ 859ad6194a2SStefano Zampini #define __FUNCT__ "MatDuplicate_IS" 860ad6194a2SStefano Zampini PetscErrorCode MatDuplicate_IS(Mat mat,MatDuplicateOption op,Mat *newmat) 861ad6194a2SStefano Zampini { 862ad6194a2SStefano Zampini PetscErrorCode ierr; 863ad6194a2SStefano Zampini Mat_IS *matis = (Mat_IS*)(mat->data); 864ad6194a2SStefano Zampini PetscInt bs,m,n,M,N; 865ad6194a2SStefano Zampini Mat B,localmat; 866ad6194a2SStefano Zampini 867ad6194a2SStefano Zampini PetscFunctionBegin; 868ad6194a2SStefano Zampini ierr = MatGetBlockSize(mat,&bs);CHKERRQ(ierr); 869ad6194a2SStefano Zampini ierr = MatGetSize(mat,&M,&N);CHKERRQ(ierr); 870ad6194a2SStefano Zampini ierr = MatGetLocalSize(mat,&m,&n);CHKERRQ(ierr); 871e176bc59SStefano Zampini ierr = MatCreateIS(PetscObjectComm((PetscObject)mat),bs,m,n,M,N,mat->rmap->mapping,mat->cmap->mapping,&B);CHKERRQ(ierr); 872ad6194a2SStefano Zampini ierr = MatDuplicate(matis->A,op,&localmat);CHKERRQ(ierr); 873ad6194a2SStefano Zampini ierr = MatISSetLocalMat(B,localmat);CHKERRQ(ierr); 874b3317aa8SStefano Zampini ierr = MatDestroy(&localmat);CHKERRQ(ierr); 875ad6194a2SStefano Zampini ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 876ad6194a2SStefano Zampini ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 877ad6194a2SStefano Zampini *newmat = B; 878ad6194a2SStefano Zampini PetscFunctionReturn(0); 879ad6194a2SStefano Zampini } 880ad6194a2SStefano Zampini 881ad6194a2SStefano Zampini #undef __FUNCT__ 88269796d55SStefano Zampini #define __FUNCT__ "MatIsHermitian_IS" 883a8116848SStefano Zampini static PetscErrorCode MatIsHermitian_IS(Mat A,PetscReal tol,PetscBool *flg) 88469796d55SStefano Zampini { 88569796d55SStefano Zampini PetscErrorCode ierr; 88669796d55SStefano Zampini Mat_IS *matis = (Mat_IS*)A->data; 88769796d55SStefano Zampini PetscBool local_sym; 88869796d55SStefano Zampini 88969796d55SStefano Zampini PetscFunctionBegin; 89069796d55SStefano Zampini ierr = MatIsHermitian(matis->A,tol,&local_sym);CHKERRQ(ierr); 891b2566f29SBarry Smith ierr = MPIU_Allreduce(&local_sym,flg,1,MPIU_BOOL,MPI_LAND,PetscObjectComm((PetscObject)A));CHKERRQ(ierr); 89269796d55SStefano Zampini PetscFunctionReturn(0); 89369796d55SStefano Zampini } 89469796d55SStefano Zampini 89569796d55SStefano Zampini #undef __FUNCT__ 89669796d55SStefano Zampini #define __FUNCT__ "MatIsSymmetric_IS" 897a8116848SStefano Zampini static PetscErrorCode MatIsSymmetric_IS(Mat A,PetscReal tol,PetscBool *flg) 89869796d55SStefano Zampini { 89969796d55SStefano Zampini PetscErrorCode ierr; 90069796d55SStefano Zampini Mat_IS *matis = (Mat_IS*)A->data; 90169796d55SStefano Zampini PetscBool local_sym; 90269796d55SStefano Zampini 90369796d55SStefano Zampini PetscFunctionBegin; 90469796d55SStefano Zampini ierr = MatIsSymmetric(matis->A,tol,&local_sym);CHKERRQ(ierr); 905b2566f29SBarry Smith ierr = MPIU_Allreduce(&local_sym,flg,1,MPIU_BOOL,MPI_LAND,PetscObjectComm((PetscObject)A));CHKERRQ(ierr); 90669796d55SStefano Zampini PetscFunctionReturn(0); 90769796d55SStefano Zampini } 90869796d55SStefano Zampini 90969796d55SStefano Zampini #undef __FUNCT__ 910b4319ba4SBarry Smith #define __FUNCT__ "MatDestroy_IS" 911a8116848SStefano Zampini static PetscErrorCode MatDestroy_IS(Mat A) 912b4319ba4SBarry Smith { 913dfbe8321SBarry Smith PetscErrorCode ierr; 914b4319ba4SBarry Smith Mat_IS *b = (Mat_IS*)A->data; 915b4319ba4SBarry Smith 916b4319ba4SBarry Smith PetscFunctionBegin; 9176bf464f9SBarry Smith ierr = MatDestroy(&b->A);CHKERRQ(ierr); 918e176bc59SStefano Zampini ierr = VecScatterDestroy(&b->cctx);CHKERRQ(ierr); 919e176bc59SStefano Zampini ierr = VecScatterDestroy(&b->rctx);CHKERRQ(ierr); 9206bf464f9SBarry Smith ierr = VecDestroy(&b->x);CHKERRQ(ierr); 9216bf464f9SBarry Smith ierr = VecDestroy(&b->y);CHKERRQ(ierr); 9223fd1c9e7SStefano Zampini ierr = VecDestroy(&b->counter);CHKERRQ(ierr); 923a8116848SStefano Zampini ierr = ISDestroy(&b->getsub_ris);CHKERRQ(ierr); 924a8116848SStefano Zampini ierr = ISDestroy(&b->getsub_cis);CHKERRQ(ierr); 925a8116848SStefano Zampini if (b->sf != b->csf) { 926a8116848SStefano Zampini ierr = PetscSFDestroy(&b->csf);CHKERRQ(ierr); 927a8116848SStefano Zampini ierr = PetscFree2(b->csf_rootdata,b->csf_leafdata);CHKERRQ(ierr); 928a8116848SStefano Zampini } 92928f4e0baSStefano Zampini ierr = PetscSFDestroy(&b->sf);CHKERRQ(ierr); 93028f4e0baSStefano Zampini ierr = PetscFree2(b->sf_rootdata,b->sf_leafdata);CHKERRQ(ierr); 931bf0cc555SLisandro Dalcin ierr = PetscFree(A->data);CHKERRQ(ierr); 932dbd8c25aSHong Zhang ierr = PetscObjectChangeTypeName((PetscObject)A,0);CHKERRQ(ierr); 933bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatISGetLocalMat_C",NULL);CHKERRQ(ierr); 934b7ce53b6SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatISSetLocalMat_C",NULL);CHKERRQ(ierr); 935b7ce53b6SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatISGetMPIXAIJ_C",NULL);CHKERRQ(ierr); 9362e1947a5SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatISSetPreallocation_C",NULL);CHKERRQ(ierr); 937b4319ba4SBarry Smith PetscFunctionReturn(0); 938b4319ba4SBarry Smith } 939b4319ba4SBarry Smith 940b4319ba4SBarry Smith #undef __FUNCT__ 941b4319ba4SBarry Smith #define __FUNCT__ "MatMult_IS" 942a8116848SStefano Zampini static PetscErrorCode MatMult_IS(Mat A,Vec x,Vec y) 943b4319ba4SBarry Smith { 944dfbe8321SBarry Smith PetscErrorCode ierr; 945b4319ba4SBarry Smith Mat_IS *is = (Mat_IS*)A->data; 946b4319ba4SBarry Smith PetscScalar zero = 0.0; 947b4319ba4SBarry Smith 948b4319ba4SBarry Smith PetscFunctionBegin; 949b4319ba4SBarry Smith /* scatter the global vector x into the local work vector */ 950e176bc59SStefano Zampini ierr = VecScatterBegin(is->cctx,x,is->x,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 951e176bc59SStefano Zampini ierr = VecScatterEnd(is->cctx,x,is->x,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 952b4319ba4SBarry Smith 953b4319ba4SBarry Smith /* multiply the local matrix */ 954b4319ba4SBarry Smith ierr = MatMult(is->A,is->x,is->y);CHKERRQ(ierr); 955b4319ba4SBarry Smith 956b4319ba4SBarry Smith /* scatter product back into global memory */ 9572dcb1b2aSMatthew Knepley ierr = VecSet(y,zero);CHKERRQ(ierr); 958e176bc59SStefano Zampini ierr = VecScatterBegin(is->rctx,is->y,y,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 959e176bc59SStefano Zampini ierr = VecScatterEnd(is->rctx,is->y,y,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 960b4319ba4SBarry Smith PetscFunctionReturn(0); 961b4319ba4SBarry Smith } 962b4319ba4SBarry Smith 963b4319ba4SBarry Smith #undef __FUNCT__ 9642e74eeadSLisandro Dalcin #define __FUNCT__ "MatMultAdd_IS" 965a8116848SStefano Zampini static PetscErrorCode MatMultAdd_IS(Mat A,Vec v1,Vec v2,Vec v3) 9662e74eeadSLisandro Dalcin { 967650997f4SStefano Zampini Vec temp_vec; 9682e74eeadSLisandro Dalcin PetscErrorCode ierr; 9692e74eeadSLisandro Dalcin 9702e74eeadSLisandro Dalcin PetscFunctionBegin; /* v3 = v2 + A * v1.*/ 971650997f4SStefano Zampini if (v3 != v2) { 972650997f4SStefano Zampini ierr = MatMult(A,v1,v3);CHKERRQ(ierr); 973650997f4SStefano Zampini ierr = VecAXPY(v3,1.0,v2);CHKERRQ(ierr); 974650997f4SStefano Zampini } else { 975650997f4SStefano Zampini ierr = VecDuplicate(v2,&temp_vec);CHKERRQ(ierr); 976650997f4SStefano Zampini ierr = MatMult(A,v1,temp_vec);CHKERRQ(ierr); 977650997f4SStefano Zampini ierr = VecAXPY(temp_vec,1.0,v2);CHKERRQ(ierr); 978650997f4SStefano Zampini ierr = VecCopy(temp_vec,v3);CHKERRQ(ierr); 979650997f4SStefano Zampini ierr = VecDestroy(&temp_vec);CHKERRQ(ierr); 980650997f4SStefano Zampini } 9812e74eeadSLisandro Dalcin PetscFunctionReturn(0); 9822e74eeadSLisandro Dalcin } 9832e74eeadSLisandro Dalcin 9842e74eeadSLisandro Dalcin #undef __FUNCT__ 9852e74eeadSLisandro Dalcin #define __FUNCT__ "MatMultTranspose_IS" 986a8116848SStefano Zampini static PetscErrorCode MatMultTranspose_IS(Mat A,Vec y,Vec x) 9872e74eeadSLisandro Dalcin { 9882e74eeadSLisandro Dalcin Mat_IS *is = (Mat_IS*)A->data; 9892e74eeadSLisandro Dalcin PetscErrorCode ierr; 9902e74eeadSLisandro Dalcin 991e176bc59SStefano Zampini PetscFunctionBegin; 9922e74eeadSLisandro Dalcin /* scatter the global vector x into the local work vector */ 993e176bc59SStefano Zampini ierr = VecScatterBegin(is->rctx,y,is->y,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 994e176bc59SStefano Zampini ierr = VecScatterEnd(is->rctx,y,is->y,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 9952e74eeadSLisandro Dalcin 9962e74eeadSLisandro Dalcin /* multiply the local matrix */ 997e176bc59SStefano Zampini ierr = MatMultTranspose(is->A,is->y,is->x);CHKERRQ(ierr); 9982e74eeadSLisandro Dalcin 9992e74eeadSLisandro Dalcin /* scatter product back into global vector */ 1000e176bc59SStefano Zampini ierr = VecSet(x,0);CHKERRQ(ierr); 1001e176bc59SStefano Zampini ierr = VecScatterBegin(is->cctx,is->x,x,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 1002e176bc59SStefano Zampini ierr = VecScatterEnd(is->cctx,is->x,x,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 10032e74eeadSLisandro Dalcin PetscFunctionReturn(0); 10042e74eeadSLisandro Dalcin } 10052e74eeadSLisandro Dalcin 10062e74eeadSLisandro Dalcin #undef __FUNCT__ 10072e74eeadSLisandro Dalcin #define __FUNCT__ "MatMultTransposeAdd_IS" 1008a8116848SStefano Zampini static PetscErrorCode MatMultTransposeAdd_IS(Mat A,Vec v1,Vec v2,Vec v3) 10092e74eeadSLisandro Dalcin { 1010650997f4SStefano Zampini Vec temp_vec; 10112e74eeadSLisandro Dalcin PetscErrorCode ierr; 10122e74eeadSLisandro Dalcin 10132e74eeadSLisandro Dalcin PetscFunctionBegin; /* v3 = v2 + A' * v1.*/ 1014650997f4SStefano Zampini if (v3 != v2) { 1015650997f4SStefano Zampini ierr = MatMultTranspose(A,v1,v3);CHKERRQ(ierr); 1016650997f4SStefano Zampini ierr = VecAXPY(v3,1.0,v2);CHKERRQ(ierr); 1017650997f4SStefano Zampini } else { 1018650997f4SStefano Zampini ierr = VecDuplicate(v2,&temp_vec);CHKERRQ(ierr); 1019650997f4SStefano Zampini ierr = MatMultTranspose(A,v1,temp_vec);CHKERRQ(ierr); 1020650997f4SStefano Zampini ierr = VecAXPY(temp_vec,1.0,v2);CHKERRQ(ierr); 1021650997f4SStefano Zampini ierr = VecCopy(temp_vec,v3);CHKERRQ(ierr); 1022650997f4SStefano Zampini ierr = VecDestroy(&temp_vec);CHKERRQ(ierr); 1023650997f4SStefano Zampini } 10242e74eeadSLisandro Dalcin PetscFunctionReturn(0); 10252e74eeadSLisandro Dalcin } 10262e74eeadSLisandro Dalcin 10272e74eeadSLisandro Dalcin #undef __FUNCT__ 1028b4319ba4SBarry Smith #define __FUNCT__ "MatView_IS" 1029a8116848SStefano Zampini static PetscErrorCode MatView_IS(Mat A,PetscViewer viewer) 1030b4319ba4SBarry Smith { 1031b4319ba4SBarry Smith Mat_IS *a = (Mat_IS*)A->data; 1032dfbe8321SBarry Smith PetscErrorCode ierr; 1033b4319ba4SBarry Smith PetscViewer sviewer; 1034b4319ba4SBarry Smith 1035b4319ba4SBarry Smith PetscFunctionBegin; 10363f08860eSBarry Smith ierr = PetscViewerGetSubViewer(viewer,PETSC_COMM_SELF,&sviewer);CHKERRQ(ierr); 1037b4319ba4SBarry Smith ierr = MatView(a->A,sviewer);CHKERRQ(ierr); 10383f08860eSBarry Smith ierr = PetscViewerRestoreSubViewer(viewer,PETSC_COMM_SELF,&sviewer);CHKERRQ(ierr); 10396e520ac8SStefano Zampini ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 1040b4319ba4SBarry Smith PetscFunctionReturn(0); 1041b4319ba4SBarry Smith } 1042b4319ba4SBarry Smith 1043b4319ba4SBarry Smith #undef __FUNCT__ 1044b4319ba4SBarry Smith #define __FUNCT__ "MatSetLocalToGlobalMapping_IS" 1045a8116848SStefano Zampini static PetscErrorCode MatSetLocalToGlobalMapping_IS(Mat A,ISLocalToGlobalMapping rmapping,ISLocalToGlobalMapping cmapping) 1046b4319ba4SBarry Smith { 1047dfbe8321SBarry Smith PetscErrorCode ierr; 1048e176bc59SStefano Zampini PetscInt nr,rbs,nc,cbs; 1049b4319ba4SBarry Smith Mat_IS *is = (Mat_IS*)A->data; 1050b4319ba4SBarry Smith IS from,to; 1051e176bc59SStefano Zampini Vec cglobal,rglobal; 1052b4319ba4SBarry Smith 1053b4319ba4SBarry Smith PetscFunctionBegin; 1054784ac674SJed Brown PetscCheckSameComm(A,1,rmapping,2); 1055e176bc59SStefano Zampini PetscCheckSameComm(A,1,cmapping,3); 10563bbff08aSStefano Zampini /* Destroy any previous data */ 105770cf5478SStefano Zampini ierr = VecDestroy(&is->x);CHKERRQ(ierr); 105870cf5478SStefano Zampini ierr = VecDestroy(&is->y);CHKERRQ(ierr); 10593fd1c9e7SStefano Zampini ierr = VecDestroy(&is->counter);CHKERRQ(ierr); 1060e176bc59SStefano Zampini ierr = VecScatterDestroy(&is->rctx);CHKERRQ(ierr); 1061e176bc59SStefano Zampini ierr = VecScatterDestroy(&is->cctx);CHKERRQ(ierr); 10621c47cb0fSStefano Zampini ierr = MatDestroy(&is->A);CHKERRQ(ierr); 106328f4e0baSStefano Zampini ierr = PetscSFDestroy(&is->sf);CHKERRQ(ierr); 106428f4e0baSStefano Zampini ierr = PetscFree2(is->sf_rootdata,is->sf_leafdata);CHKERRQ(ierr); 10653bbff08aSStefano Zampini 10663bbff08aSStefano Zampini /* Setup Layout and set local to global maps */ 1067fc27028aSStefano Zampini ierr = PetscLayoutSetUp(A->rmap);CHKERRQ(ierr); 1068fc27028aSStefano Zampini ierr = PetscLayoutSetUp(A->cmap);CHKERRQ(ierr); 1069fa7f1dd8SStefano Zampini ierr = PetscLayoutSetISLocalToGlobalMapping(A->rmap,rmapping);CHKERRQ(ierr); 1070fa7f1dd8SStefano Zampini ierr = PetscLayoutSetISLocalToGlobalMapping(A->cmap,cmapping);CHKERRQ(ierr); 1071b4319ba4SBarry Smith 1072b4319ba4SBarry Smith /* Create the local matrix A */ 1073e176bc59SStefano Zampini ierr = ISLocalToGlobalMappingGetSize(rmapping,&nr);CHKERRQ(ierr); 1074e176bc59SStefano Zampini ierr = ISLocalToGlobalMappingGetBlockSize(rmapping,&rbs);CHKERRQ(ierr); 1075e176bc59SStefano Zampini ierr = ISLocalToGlobalMappingGetSize(cmapping,&nc);CHKERRQ(ierr); 1076e176bc59SStefano Zampini ierr = ISLocalToGlobalMappingGetBlockSize(cmapping,&cbs);CHKERRQ(ierr); 1077f69a0ea3SMatthew Knepley ierr = MatCreate(PETSC_COMM_SELF,&is->A);CHKERRQ(ierr); 1078e176bc59SStefano Zampini ierr = MatSetType(is->A,MATAIJ);CHKERRQ(ierr); 1079e176bc59SStefano Zampini ierr = MatSetSizes(is->A,nr,nc,nr,nc);CHKERRQ(ierr); 1080e176bc59SStefano Zampini ierr = MatSetBlockSizes(is->A,rbs,cbs);CHKERRQ(ierr); 1081ff130e51SJed Brown ierr = MatSetOptionsPrefix(is->A,((PetscObject)A)->prefix);CHKERRQ(ierr); 1082ff130e51SJed Brown ierr = MatAppendOptionsPrefix(is->A,"is_");CHKERRQ(ierr); 1083b4319ba4SBarry Smith ierr = MatSetFromOptions(is->A);CHKERRQ(ierr); 1084b4319ba4SBarry Smith 1085f26d0771SStefano Zampini if (!is->islocalref) { /* setup scatters and local vectors for MatMult */ 1086b4319ba4SBarry Smith /* Create the local work vectors */ 10873bbff08aSStefano Zampini ierr = MatCreateVecs(is->A,&is->x,&is->y);CHKERRQ(ierr); 1088b4319ba4SBarry Smith 1089e176bc59SStefano Zampini /* setup the global to local scatters */ 1090e176bc59SStefano Zampini ierr = MatCreateVecs(A,&cglobal,&rglobal);CHKERRQ(ierr); 1091e176bc59SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,nr,0,1,&to);CHKERRQ(ierr); 1092784ac674SJed Brown ierr = ISLocalToGlobalMappingApplyIS(rmapping,to,&from);CHKERRQ(ierr); 1093e176bc59SStefano Zampini ierr = VecScatterCreate(rglobal,from,is->y,to,&is->rctx);CHKERRQ(ierr); 1094e176bc59SStefano Zampini if (rmapping != cmapping) { 1095e176bc59SStefano Zampini ierr = ISDestroy(&to);CHKERRQ(ierr); 1096e176bc59SStefano Zampini ierr = ISDestroy(&from);CHKERRQ(ierr); 1097e176bc59SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,nc,0,1,&to);CHKERRQ(ierr); 1098e176bc59SStefano Zampini ierr = ISLocalToGlobalMappingApplyIS(cmapping,to,&from);CHKERRQ(ierr); 1099e176bc59SStefano Zampini ierr = VecScatterCreate(cglobal,from,is->x,to,&is->cctx);CHKERRQ(ierr); 1100e176bc59SStefano Zampini } else { 1101e176bc59SStefano Zampini ierr = PetscObjectReference((PetscObject)is->rctx);CHKERRQ(ierr); 1102e176bc59SStefano Zampini is->cctx = is->rctx; 1103e176bc59SStefano Zampini } 11043fd1c9e7SStefano Zampini 11053fd1c9e7SStefano Zampini /* interface counter vector (local) */ 11063fd1c9e7SStefano Zampini ierr = VecDuplicate(is->y,&is->counter);CHKERRQ(ierr); 11073fd1c9e7SStefano Zampini ierr = VecSet(is->y,1.);CHKERRQ(ierr); 11083fd1c9e7SStefano Zampini ierr = VecScatterBegin(is->rctx,is->y,rglobal,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 11093fd1c9e7SStefano Zampini ierr = VecScatterEnd(is->rctx,is->y,rglobal,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 11103fd1c9e7SStefano Zampini ierr = VecScatterBegin(is->rctx,rglobal,is->counter,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 11113fd1c9e7SStefano Zampini ierr = VecScatterEnd(is->rctx,rglobal,is->counter,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 11123fd1c9e7SStefano Zampini 11133fd1c9e7SStefano Zampini /* free workspace */ 1114e176bc59SStefano Zampini ierr = VecDestroy(&rglobal);CHKERRQ(ierr); 1115e176bc59SStefano Zampini ierr = VecDestroy(&cglobal);CHKERRQ(ierr); 11166bf464f9SBarry Smith ierr = ISDestroy(&to);CHKERRQ(ierr); 11176bf464f9SBarry Smith ierr = ISDestroy(&from);CHKERRQ(ierr); 1118f26d0771SStefano Zampini } 111948ff6bf3SStefano Zampini ierr = MatSetUp(A);CHKERRQ(ierr); 1120b4319ba4SBarry Smith PetscFunctionReturn(0); 1121b4319ba4SBarry Smith } 1122b4319ba4SBarry Smith 11232e74eeadSLisandro Dalcin #undef __FUNCT__ 11242e74eeadSLisandro Dalcin #define __FUNCT__ "MatSetValues_IS" 1125a8116848SStefano Zampini static PetscErrorCode MatSetValues_IS(Mat mat, PetscInt m,const PetscInt *rows, PetscInt n,const PetscInt *cols, const PetscScalar *values, InsertMode addv) 11262e74eeadSLisandro Dalcin { 11272e74eeadSLisandro Dalcin Mat_IS *is = (Mat_IS*)mat->data; 11282e74eeadSLisandro Dalcin PetscErrorCode ierr; 112997563a80SStefano Zampini #if defined(PETSC_USE_DEBUG) 113097563a80SStefano Zampini PetscInt i,zm,zn; 113197563a80SStefano Zampini #endif 1132f26d0771SStefano Zampini PetscInt rows_l[MATIS_MAX_ENTRIES_INSERTION],cols_l[MATIS_MAX_ENTRIES_INSERTION]; 11332e74eeadSLisandro Dalcin 11342e74eeadSLisandro Dalcin PetscFunctionBegin; 11352e74eeadSLisandro Dalcin #if defined(PETSC_USE_DEBUG) 1136f26d0771SStefano 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); 113797563a80SStefano Zampini /* count negative indices */ 113897563a80SStefano Zampini for (i=0,zm=0;i<m;i++) if (rows[i] < 0) zm++; 113997563a80SStefano Zampini for (i=0,zn=0;i<n;i++) if (cols[i] < 0) zn++; 11402e74eeadSLisandro Dalcin #endif 114197563a80SStefano Zampini ierr = ISGlobalToLocalMappingApply(mat->rmap->mapping,IS_GTOLM_MASK,m,rows,&m,rows_l);CHKERRQ(ierr); 114297563a80SStefano Zampini ierr = ISGlobalToLocalMappingApply(mat->cmap->mapping,IS_GTOLM_MASK,n,cols,&n,cols_l);CHKERRQ(ierr); 114397563a80SStefano Zampini #if defined(PETSC_USE_DEBUG) 114497563a80SStefano Zampini /* count negative indices (should be the same as before) */ 114597563a80SStefano Zampini for (i=0;i<m;i++) if (rows_l[i] < 0) zm--; 114697563a80SStefano Zampini for (i=0;i<n;i++) if (cols_l[i] < 0) zn--; 114797563a80SStefano 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"); 114897563a80SStefano 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"); 114997563a80SStefano Zampini #endif 11502e74eeadSLisandro Dalcin ierr = MatSetValues(is->A,m,rows_l,n,cols_l,values,addv);CHKERRQ(ierr); 11512e74eeadSLisandro Dalcin PetscFunctionReturn(0); 11522e74eeadSLisandro Dalcin } 11532e74eeadSLisandro Dalcin 1154b4319ba4SBarry Smith #undef __FUNCT__ 115597563a80SStefano Zampini #define __FUNCT__ "MatSetValuesBlocked_IS" 1156a8116848SStefano Zampini static PetscErrorCode MatSetValuesBlocked_IS(Mat mat, PetscInt m,const PetscInt *rows, PetscInt n,const PetscInt *cols, const PetscScalar *values, InsertMode addv) 115797563a80SStefano Zampini { 115897563a80SStefano Zampini Mat_IS *is = (Mat_IS*)mat->data; 115997563a80SStefano Zampini PetscErrorCode ierr; 116097563a80SStefano Zampini #if defined(PETSC_USE_DEBUG) 116197563a80SStefano Zampini PetscInt i,zm,zn; 116297563a80SStefano Zampini #endif 1163f26d0771SStefano Zampini PetscInt rows_l[MATIS_MAX_ENTRIES_INSERTION],cols_l[MATIS_MAX_ENTRIES_INSERTION]; 116497563a80SStefano Zampini 116597563a80SStefano Zampini PetscFunctionBegin; 116697563a80SStefano Zampini #if defined(PETSC_USE_DEBUG) 1167f26d0771SStefano 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); 116897563a80SStefano Zampini /* count negative indices */ 116997563a80SStefano Zampini for (i=0,zm=0;i<m;i++) if (rows[i] < 0) zm++; 117097563a80SStefano Zampini for (i=0,zn=0;i<n;i++) if (cols[i] < 0) zn++; 117197563a80SStefano Zampini #endif 117297563a80SStefano Zampini ierr = ISGlobalToLocalMappingApplyBlock(mat->rmap->mapping,IS_GTOLM_MASK,m,rows,&m,rows_l);CHKERRQ(ierr); 117397563a80SStefano Zampini ierr = ISGlobalToLocalMappingApplyBlock(mat->cmap->mapping,IS_GTOLM_MASK,n,cols,&n,cols_l);CHKERRQ(ierr); 117497563a80SStefano Zampini #if defined(PETSC_USE_DEBUG) 117597563a80SStefano Zampini /* count negative indices (should be the same as before) */ 117697563a80SStefano Zampini for (i=0;i<m;i++) if (rows_l[i] < 0) zm--; 117797563a80SStefano Zampini for (i=0;i<n;i++) if (cols_l[i] < 0) zn--; 117897563a80SStefano 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"); 117997563a80SStefano 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"); 118097563a80SStefano Zampini #endif 118197563a80SStefano Zampini ierr = MatSetValuesBlocked(is->A,m,rows_l,n,cols_l,values,addv);CHKERRQ(ierr); 118297563a80SStefano Zampini PetscFunctionReturn(0); 118397563a80SStefano Zampini } 118497563a80SStefano Zampini 118597563a80SStefano Zampini #undef __FUNCT__ 1186b4319ba4SBarry Smith #define __FUNCT__ "MatSetValuesLocal_IS" 1187a8116848SStefano Zampini static PetscErrorCode MatSetValuesLocal_IS(Mat A,PetscInt m,const PetscInt *rows, PetscInt n,const PetscInt *cols,const PetscScalar *values,InsertMode addv) 1188b4319ba4SBarry Smith { 1189dfbe8321SBarry Smith PetscErrorCode ierr; 1190b4319ba4SBarry Smith Mat_IS *is = (Mat_IS*)A->data; 1191b4319ba4SBarry Smith 1192b4319ba4SBarry Smith PetscFunctionBegin; 1193b4319ba4SBarry Smith ierr = MatSetValues(is->A,m,rows,n,cols,values,addv);CHKERRQ(ierr); 1194b4319ba4SBarry Smith PetscFunctionReturn(0); 1195b4319ba4SBarry Smith } 1196b4319ba4SBarry Smith 1197b4319ba4SBarry Smith #undef __FUNCT__ 1198f0006bf2SLisandro Dalcin #define __FUNCT__ "MatSetValuesBlockedLocal_IS" 1199a8116848SStefano Zampini static PetscErrorCode MatSetValuesBlockedLocal_IS(Mat A,PetscInt m,const PetscInt *rows, PetscInt n,const PetscInt *cols,const PetscScalar *values,InsertMode addv) 1200f0006bf2SLisandro Dalcin { 1201f0006bf2SLisandro Dalcin PetscErrorCode ierr; 1202f0006bf2SLisandro Dalcin Mat_IS *is = (Mat_IS*)A->data; 1203f0006bf2SLisandro Dalcin 1204f0006bf2SLisandro Dalcin PetscFunctionBegin; 1205f0006bf2SLisandro Dalcin ierr = MatSetValuesBlocked(is->A,m,rows,n,cols,values,addv);CHKERRQ(ierr); 1206f0006bf2SLisandro Dalcin PetscFunctionReturn(0); 1207f0006bf2SLisandro Dalcin } 1208f0006bf2SLisandro Dalcin 1209f0006bf2SLisandro Dalcin #undef __FUNCT__ 1210f0ae7da4SStefano Zampini #define __FUNCT__ "MatISZeroRowsColumnsLocal_Private" 1211f0ae7da4SStefano Zampini static PetscErrorCode MatISZeroRowsColumnsLocal_Private(Mat A,PetscInt n,const PetscInt rows[],PetscScalar diag,PetscBool columns) 1212f0ae7da4SStefano Zampini { 1213f0ae7da4SStefano Zampini Mat_IS *is = (Mat_IS*)A->data; 1214f0ae7da4SStefano Zampini PetscErrorCode ierr; 1215f0ae7da4SStefano Zampini 1216f0ae7da4SStefano Zampini PetscFunctionBegin; 1217f0ae7da4SStefano Zampini if (!n) { 1218f0ae7da4SStefano Zampini is->pure_neumann = PETSC_TRUE; 1219f0ae7da4SStefano Zampini } else { 1220f0ae7da4SStefano Zampini PetscInt i; 1221f0ae7da4SStefano Zampini is->pure_neumann = PETSC_FALSE; 1222f0ae7da4SStefano Zampini 1223f0ae7da4SStefano Zampini if (columns) { 1224f0ae7da4SStefano Zampini ierr = MatZeroRowsColumns(is->A,n,rows,diag,0,0);CHKERRQ(ierr); 1225f0ae7da4SStefano Zampini } else { 1226f0ae7da4SStefano Zampini ierr = MatZeroRows(is->A,n,rows,diag,0,0);CHKERRQ(ierr); 1227f0ae7da4SStefano Zampini } 1228f0ae7da4SStefano Zampini if (diag != 0.) { 1229f0ae7da4SStefano Zampini const PetscScalar *array; 1230f0ae7da4SStefano Zampini ierr = VecGetArrayRead(is->counter,&array);CHKERRQ(ierr); 1231f0ae7da4SStefano Zampini for (i=0; i<n; i++) { 1232f0ae7da4SStefano Zampini ierr = MatSetValue(is->A,rows[i],rows[i],diag/(array[rows[i]]),INSERT_VALUES);CHKERRQ(ierr); 1233f0ae7da4SStefano Zampini } 1234f0ae7da4SStefano Zampini ierr = VecRestoreArrayRead(is->counter,&array);CHKERRQ(ierr); 1235f0ae7da4SStefano Zampini } 1236f0ae7da4SStefano Zampini ierr = MatAssemblyBegin(is->A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1237f0ae7da4SStefano Zampini ierr = MatAssemblyEnd(is->A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1238f0ae7da4SStefano Zampini } 1239f0ae7da4SStefano Zampini PetscFunctionReturn(0); 1240f0ae7da4SStefano Zampini } 1241f0ae7da4SStefano Zampini 1242f0ae7da4SStefano Zampini #undef __FUNCT__ 1243f0ae7da4SStefano Zampini #define __FUNCT__ "MatZeroRowsColumns_Private_IS" 1244f0ae7da4SStefano Zampini static PetscErrorCode MatZeroRowsColumns_Private_IS(Mat A,PetscInt n,const PetscInt rows[],PetscScalar diag,Vec x,Vec b,PetscBool columns) 12452e74eeadSLisandro Dalcin { 12466e520ac8SStefano Zampini Mat_IS *matis = (Mat_IS*)A->data; 12476e520ac8SStefano Zampini PetscInt nr,nl,len,i; 12486e520ac8SStefano Zampini PetscInt *lrows; 12492e74eeadSLisandro Dalcin PetscErrorCode ierr; 12502e74eeadSLisandro Dalcin 12512e74eeadSLisandro Dalcin PetscFunctionBegin; 1252f0ae7da4SStefano Zampini #if defined(PETSC_USE_DEBUG) 1253f0ae7da4SStefano Zampini if (columns || diag != 0. || (x && b)) { 1254f0ae7da4SStefano Zampini PetscBool cong; 1255f0ae7da4SStefano Zampini ierr = PetscLayoutCompare(A->rmap,A->cmap,&cong);CHKERRQ(ierr); 1256f0ae7da4SStefano 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"); 1257f0ae7da4SStefano 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"); 1258f0ae7da4SStefano Zampini if (!cong && x && b) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"A->rmap and A->cmap need to be congruent"); 1259f0ae7da4SStefano Zampini } 1260f0ae7da4SStefano Zampini #endif 12616e520ac8SStefano Zampini /* get locally owned rows */ 1262f0ae7da4SStefano Zampini ierr = PetscLayoutMapLocal_Private(A->rmap,n,rows,&len,&lrows,NULL);CHKERRQ(ierr); 12636e520ac8SStefano Zampini /* fix right hand side if needed */ 12646e520ac8SStefano Zampini if (x && b) { 12656e520ac8SStefano Zampini const PetscScalar *xx; 12666e520ac8SStefano Zampini PetscScalar *bb; 12676e520ac8SStefano Zampini 12686e520ac8SStefano Zampini ierr = VecGetArrayRead(x, &xx);CHKERRQ(ierr); 12696e520ac8SStefano Zampini ierr = VecGetArray(b, &bb);CHKERRQ(ierr); 12706e520ac8SStefano Zampini for (i=0;i<len;++i) bb[lrows[i]] = diag*xx[lrows[i]]; 12716e520ac8SStefano Zampini ierr = VecRestoreArrayRead(x, &xx);CHKERRQ(ierr); 12726e520ac8SStefano Zampini ierr = VecRestoreArray(b, &bb);CHKERRQ(ierr); 12732e74eeadSLisandro Dalcin } 12746e520ac8SStefano Zampini /* get rows associated to the local matrices */ 12756e520ac8SStefano Zampini if (!matis->sf) { /* setup SF if not yet created and allocate rootdata and leafdata */ 12766e520ac8SStefano Zampini ierr = MatISComputeSF_Private(A);CHKERRQ(ierr); 12776e520ac8SStefano Zampini } 12786e520ac8SStefano Zampini ierr = MatGetSize(matis->A,&nl,NULL);CHKERRQ(ierr); 12796e520ac8SStefano Zampini ierr = PetscMemzero(matis->sf_leafdata,nl*sizeof(PetscInt));CHKERRQ(ierr); 12806e520ac8SStefano Zampini ierr = PetscMemzero(matis->sf_rootdata,A->rmap->n*sizeof(PetscInt));CHKERRQ(ierr); 12816e520ac8SStefano Zampini for (i=0;i<len;i++) matis->sf_rootdata[lrows[i]] = 1; 12826e520ac8SStefano Zampini ierr = PetscFree(lrows);CHKERRQ(ierr); 12836e520ac8SStefano Zampini ierr = PetscSFBcastBegin(matis->sf,MPIU_INT,matis->sf_rootdata,matis->sf_leafdata);CHKERRQ(ierr); 12846e520ac8SStefano Zampini ierr = PetscSFBcastEnd(matis->sf,MPIU_INT,matis->sf_rootdata,matis->sf_leafdata);CHKERRQ(ierr); 12856e520ac8SStefano Zampini ierr = PetscMalloc1(nl,&lrows);CHKERRQ(ierr); 12866e520ac8SStefano Zampini for (i=0,nr=0;i<nl;i++) if (matis->sf_leafdata[i]) lrows[nr++] = i; 1287f0ae7da4SStefano Zampini ierr = MatISZeroRowsColumnsLocal_Private(A,nr,lrows,diag,columns);CHKERRQ(ierr); 12886e520ac8SStefano Zampini ierr = PetscFree(lrows);CHKERRQ(ierr); 12892e74eeadSLisandro Dalcin PetscFunctionReturn(0); 12902e74eeadSLisandro Dalcin } 12912e74eeadSLisandro Dalcin 12922e74eeadSLisandro Dalcin #undef __FUNCT__ 1293f0ae7da4SStefano Zampini #define __FUNCT__ "MatZeroRows_IS" 1294f0ae7da4SStefano Zampini static PetscErrorCode MatZeroRows_IS(Mat A,PetscInt n,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 1295b4319ba4SBarry Smith { 1296dfbe8321SBarry Smith PetscErrorCode ierr; 1297b4319ba4SBarry Smith 1298b4319ba4SBarry Smith PetscFunctionBegin; 1299f0ae7da4SStefano Zampini ierr = MatZeroRowsColumns_Private_IS(A,n,rows,diag,x,b,PETSC_FALSE);CHKERRQ(ierr); 1300f0ae7da4SStefano Zampini PetscFunctionReturn(0); 1301f0ae7da4SStefano Zampini } 13022205254eSKarl Rupp 1303f0ae7da4SStefano Zampini #undef __FUNCT__ 1304f0ae7da4SStefano Zampini #define __FUNCT__ "MatZeroRowsColumns_IS" 1305f0ae7da4SStefano Zampini static PetscErrorCode MatZeroRowsColumns_IS(Mat A,PetscInt n,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 1306f0ae7da4SStefano Zampini { 1307f0ae7da4SStefano Zampini PetscErrorCode ierr; 1308f0ae7da4SStefano Zampini 1309f0ae7da4SStefano Zampini PetscFunctionBegin; 1310f0ae7da4SStefano Zampini ierr = MatZeroRowsColumns_Private_IS(A,n,rows,diag,x,b,PETSC_TRUE);CHKERRQ(ierr); 1311b4319ba4SBarry Smith PetscFunctionReturn(0); 1312b4319ba4SBarry Smith } 1313b4319ba4SBarry Smith 1314b4319ba4SBarry Smith #undef __FUNCT__ 1315b4319ba4SBarry Smith #define __FUNCT__ "MatAssemblyBegin_IS" 1316a8116848SStefano Zampini static PetscErrorCode MatAssemblyBegin_IS(Mat A,MatAssemblyType type) 1317b4319ba4SBarry Smith { 1318b4319ba4SBarry Smith Mat_IS *is = (Mat_IS*)A->data; 1319dfbe8321SBarry Smith PetscErrorCode ierr; 1320b4319ba4SBarry Smith 1321b4319ba4SBarry Smith PetscFunctionBegin; 1322b4319ba4SBarry Smith ierr = MatAssemblyBegin(is->A,type);CHKERRQ(ierr); 1323b4319ba4SBarry Smith PetscFunctionReturn(0); 1324b4319ba4SBarry Smith } 1325b4319ba4SBarry Smith 1326b4319ba4SBarry Smith #undef __FUNCT__ 1327b4319ba4SBarry Smith #define __FUNCT__ "MatAssemblyEnd_IS" 1328a8116848SStefano Zampini static PetscErrorCode MatAssemblyEnd_IS(Mat A,MatAssemblyType type) 1329b4319ba4SBarry Smith { 1330b4319ba4SBarry Smith Mat_IS *is = (Mat_IS*)A->data; 1331dfbe8321SBarry Smith PetscErrorCode ierr; 1332b4319ba4SBarry Smith 1333b4319ba4SBarry Smith PetscFunctionBegin; 1334b4319ba4SBarry Smith ierr = MatAssemblyEnd(is->A,type);CHKERRQ(ierr); 1335b4319ba4SBarry Smith PetscFunctionReturn(0); 1336b4319ba4SBarry Smith } 1337b4319ba4SBarry Smith 1338b4319ba4SBarry Smith #undef __FUNCT__ 1339b4319ba4SBarry Smith #define __FUNCT__ "MatISGetLocalMat_IS" 1340a8116848SStefano Zampini static PetscErrorCode MatISGetLocalMat_IS(Mat mat,Mat *local) 1341b4319ba4SBarry Smith { 1342b4319ba4SBarry Smith Mat_IS *is = (Mat_IS*)mat->data; 1343b4319ba4SBarry Smith 1344b4319ba4SBarry Smith PetscFunctionBegin; 1345b4319ba4SBarry Smith *local = is->A; 1346b4319ba4SBarry Smith PetscFunctionReturn(0); 1347b4319ba4SBarry Smith } 1348b4319ba4SBarry Smith 1349b4319ba4SBarry Smith #undef __FUNCT__ 1350b4319ba4SBarry Smith #define __FUNCT__ "MatISGetLocalMat" 1351b4319ba4SBarry Smith /*@ 1352b4319ba4SBarry Smith MatISGetLocalMat - Gets the local matrix stored inside a MATIS matrix. 1353b4319ba4SBarry Smith 1354b4319ba4SBarry Smith Input Parameter: 1355b4319ba4SBarry Smith . mat - the matrix 1356b4319ba4SBarry Smith 1357b4319ba4SBarry Smith Output Parameter: 1358eb82efa4SStefano Zampini . local - the local matrix 1359b4319ba4SBarry Smith 1360b4319ba4SBarry Smith Level: advanced 1361b4319ba4SBarry Smith 1362b4319ba4SBarry Smith Notes: 1363b4319ba4SBarry Smith This can be called if you have precomputed the nonzero structure of the 1364b4319ba4SBarry Smith matrix and want to provide it to the inner matrix object to improve the performance 1365b4319ba4SBarry Smith of the MatSetValues() operation. 1366b4319ba4SBarry Smith 1367b4319ba4SBarry Smith .seealso: MATIS 1368b4319ba4SBarry Smith @*/ 13697087cfbeSBarry Smith PetscErrorCode MatISGetLocalMat(Mat mat,Mat *local) 1370b4319ba4SBarry Smith { 13714ac538c5SBarry Smith PetscErrorCode ierr; 1372b4319ba4SBarry Smith 1373b4319ba4SBarry Smith PetscFunctionBegin; 13740700a824SBarry Smith PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1375b4319ba4SBarry Smith PetscValidPointer(local,2); 13764ac538c5SBarry Smith ierr = PetscUseMethod(mat,"MatISGetLocalMat_C",(Mat,Mat*),(mat,local));CHKERRQ(ierr); 1377b4319ba4SBarry Smith PetscFunctionReturn(0); 1378b4319ba4SBarry Smith } 1379b4319ba4SBarry Smith 13803b03a366Sstefano_zampini #undef __FUNCT__ 13813b03a366Sstefano_zampini #define __FUNCT__ "MatISSetLocalMat_IS" 1382a8116848SStefano Zampini static PetscErrorCode MatISSetLocalMat_IS(Mat mat,Mat local) 13833b03a366Sstefano_zampini { 13843b03a366Sstefano_zampini Mat_IS *is = (Mat_IS*)mat->data; 13853b03a366Sstefano_zampini PetscInt nrows,ncols,orows,ocols; 13863b03a366Sstefano_zampini PetscErrorCode ierr; 13873b03a366Sstefano_zampini 13883b03a366Sstefano_zampini PetscFunctionBegin; 13894e4c7dbeSStefano Zampini if (is->A) { 13903b03a366Sstefano_zampini ierr = MatGetSize(is->A,&orows,&ocols);CHKERRQ(ierr); 13913b03a366Sstefano_zampini ierr = MatGetSize(local,&nrows,&ncols);CHKERRQ(ierr); 1392f0ae7da4SStefano 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); 13934e4c7dbeSStefano Zampini } 13943b03a366Sstefano_zampini ierr = PetscObjectReference((PetscObject)local);CHKERRQ(ierr); 13953b03a366Sstefano_zampini ierr = MatDestroy(&is->A);CHKERRQ(ierr); 13963b03a366Sstefano_zampini is->A = local; 13973b03a366Sstefano_zampini PetscFunctionReturn(0); 13983b03a366Sstefano_zampini } 13993b03a366Sstefano_zampini 14003b03a366Sstefano_zampini #undef __FUNCT__ 14013b03a366Sstefano_zampini #define __FUNCT__ "MatISSetLocalMat" 14023b03a366Sstefano_zampini /*@ 1403eb82efa4SStefano Zampini MatISSetLocalMat - Replace the local matrix stored inside a MATIS object. 14043b03a366Sstefano_zampini 14053b03a366Sstefano_zampini Input Parameter: 14063b03a366Sstefano_zampini . mat - the matrix 1407eb82efa4SStefano Zampini . local - the local matrix 14083b03a366Sstefano_zampini 14093b03a366Sstefano_zampini Output Parameter: 14103b03a366Sstefano_zampini 14113b03a366Sstefano_zampini Level: advanced 14123b03a366Sstefano_zampini 14133b03a366Sstefano_zampini Notes: 14143b03a366Sstefano_zampini This can be called if you have precomputed the local matrix and 14153b03a366Sstefano_zampini want to provide it to the matrix object MATIS. 14163b03a366Sstefano_zampini 14173b03a366Sstefano_zampini .seealso: MATIS 14183b03a366Sstefano_zampini @*/ 14193b03a366Sstefano_zampini PetscErrorCode MatISSetLocalMat(Mat mat,Mat local) 14203b03a366Sstefano_zampini { 14213b03a366Sstefano_zampini PetscErrorCode ierr; 14223b03a366Sstefano_zampini 14233b03a366Sstefano_zampini PetscFunctionBegin; 14243b03a366Sstefano_zampini PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1425b7ce53b6SStefano Zampini PetscValidHeaderSpecific(local,MAT_CLASSID,2); 14263b03a366Sstefano_zampini ierr = PetscUseMethod(mat,"MatISSetLocalMat_C",(Mat,Mat),(mat,local));CHKERRQ(ierr); 14273b03a366Sstefano_zampini PetscFunctionReturn(0); 14283b03a366Sstefano_zampini } 14293b03a366Sstefano_zampini 14306726f965SBarry Smith #undef __FUNCT__ 14316726f965SBarry Smith #define __FUNCT__ "MatZeroEntries_IS" 1432a8116848SStefano Zampini static PetscErrorCode MatZeroEntries_IS(Mat A) 14336726f965SBarry Smith { 14346726f965SBarry Smith Mat_IS *a = (Mat_IS*)A->data; 14356726f965SBarry Smith PetscErrorCode ierr; 14366726f965SBarry Smith 14376726f965SBarry Smith PetscFunctionBegin; 14386726f965SBarry Smith ierr = MatZeroEntries(a->A);CHKERRQ(ierr); 14396726f965SBarry Smith PetscFunctionReturn(0); 14406726f965SBarry Smith } 14416726f965SBarry Smith 14426726f965SBarry Smith #undef __FUNCT__ 14432e74eeadSLisandro Dalcin #define __FUNCT__ "MatScale_IS" 1444a8116848SStefano Zampini static PetscErrorCode MatScale_IS(Mat A,PetscScalar a) 14452e74eeadSLisandro Dalcin { 14462e74eeadSLisandro Dalcin Mat_IS *is = (Mat_IS*)A->data; 14472e74eeadSLisandro Dalcin PetscErrorCode ierr; 14482e74eeadSLisandro Dalcin 14492e74eeadSLisandro Dalcin PetscFunctionBegin; 14502e74eeadSLisandro Dalcin ierr = MatScale(is->A,a);CHKERRQ(ierr); 14512e74eeadSLisandro Dalcin PetscFunctionReturn(0); 14522e74eeadSLisandro Dalcin } 14532e74eeadSLisandro Dalcin 14542e74eeadSLisandro Dalcin #undef __FUNCT__ 14552e74eeadSLisandro Dalcin #define __FUNCT__ "MatGetDiagonal_IS" 1456a8116848SStefano Zampini static PetscErrorCode MatGetDiagonal_IS(Mat A, Vec v) 14572e74eeadSLisandro Dalcin { 14582e74eeadSLisandro Dalcin Mat_IS *is = (Mat_IS*)A->data; 14592e74eeadSLisandro Dalcin PetscErrorCode ierr; 14602e74eeadSLisandro Dalcin 14612e74eeadSLisandro Dalcin PetscFunctionBegin; 14622e74eeadSLisandro Dalcin /* get diagonal of the local matrix */ 1463e176bc59SStefano Zampini ierr = MatGetDiagonal(is->A,is->y);CHKERRQ(ierr); 14642e74eeadSLisandro Dalcin 14652e74eeadSLisandro Dalcin /* scatter diagonal back into global vector */ 14662e74eeadSLisandro Dalcin ierr = VecSet(v,0);CHKERRQ(ierr); 1467e176bc59SStefano Zampini ierr = VecScatterBegin(is->rctx,is->y,v,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 1468e176bc59SStefano Zampini ierr = VecScatterEnd(is->rctx,is->y,v,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 14692e74eeadSLisandro Dalcin PetscFunctionReturn(0); 14702e74eeadSLisandro Dalcin } 14712e74eeadSLisandro Dalcin 14722e74eeadSLisandro Dalcin #undef __FUNCT__ 14736726f965SBarry Smith #define __FUNCT__ "MatSetOption_IS" 1474a8116848SStefano Zampini static PetscErrorCode MatSetOption_IS(Mat A,MatOption op,PetscBool flg) 14756726f965SBarry Smith { 14766726f965SBarry Smith Mat_IS *a = (Mat_IS*)A->data; 14776726f965SBarry Smith PetscErrorCode ierr; 14786726f965SBarry Smith 14796726f965SBarry Smith PetscFunctionBegin; 14804e0d8c25SBarry Smith ierr = MatSetOption(a->A,op,flg);CHKERRQ(ierr); 14816726f965SBarry Smith PetscFunctionReturn(0); 14826726f965SBarry Smith } 14836726f965SBarry Smith 1484284134d9SBarry Smith #undef __FUNCT__ 1485f26d0771SStefano Zampini #define __FUNCT__ "MatAXPY_IS" 1486f26d0771SStefano Zampini static PetscErrorCode MatAXPY_IS(Mat Y,PetscScalar a,Mat X,MatStructure str) 1487f26d0771SStefano Zampini { 1488f26d0771SStefano Zampini Mat_IS *y = (Mat_IS*)Y->data; 1489f26d0771SStefano Zampini Mat_IS *x; 1490f26d0771SStefano Zampini #if defined(PETSC_USE_DEBUG) 1491f26d0771SStefano Zampini PetscBool ismatis; 1492f26d0771SStefano Zampini #endif 1493f26d0771SStefano Zampini PetscErrorCode ierr; 1494f26d0771SStefano Zampini 1495f26d0771SStefano Zampini PetscFunctionBegin; 1496f26d0771SStefano Zampini #if defined(PETSC_USE_DEBUG) 1497f26d0771SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)X,MATIS,&ismatis);CHKERRQ(ierr); 1498f26d0771SStefano Zampini if (!ismatis) SETERRQ(PetscObjectComm((PetscObject)Y),PETSC_ERR_SUP,"Cannot call MatAXPY(Y,a,X,str) with X not of type MATIS"); 1499f26d0771SStefano Zampini #endif 1500f26d0771SStefano Zampini x = (Mat_IS*)X->data; 1501f26d0771SStefano Zampini ierr = MatAXPY(y->A,a,x->A,str);CHKERRQ(ierr); 1502f26d0771SStefano Zampini PetscFunctionReturn(0); 1503f26d0771SStefano Zampini } 1504f26d0771SStefano Zampini 1505f26d0771SStefano Zampini #undef __FUNCT__ 1506f26d0771SStefano Zampini #define __FUNCT__ "MatGetLocalSubMatrix_IS" 1507f26d0771SStefano Zampini static PetscErrorCode MatGetLocalSubMatrix_IS(Mat A,IS row,IS col,Mat *submat) 1508f26d0771SStefano Zampini { 1509f26d0771SStefano Zampini Mat lA; 1510f26d0771SStefano Zampini Mat_IS *matis; 1511f26d0771SStefano Zampini ISLocalToGlobalMapping rl2g,cl2g; 1512f26d0771SStefano Zampini IS is; 1513f26d0771SStefano Zampini const PetscInt *rg,*rl; 1514f26d0771SStefano Zampini PetscInt nrg; 1515f26d0771SStefano Zampini PetscInt N,M,nrl,i,*idxs; 1516f26d0771SStefano Zampini PetscErrorCode ierr; 1517f26d0771SStefano Zampini 1518f26d0771SStefano Zampini PetscFunctionBegin; 1519f26d0771SStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(A->rmap->mapping,&rg);CHKERRQ(ierr); 1520f26d0771SStefano Zampini ierr = ISGetLocalSize(row,&nrl);CHKERRQ(ierr); 1521f26d0771SStefano Zampini ierr = ISGetIndices(row,&rl);CHKERRQ(ierr); 1522f26d0771SStefano Zampini ierr = ISLocalToGlobalMappingGetSize(A->rmap->mapping,&nrg);CHKERRQ(ierr); 1523f26d0771SStefano Zampini #if defined(PETSC_USE_DEBUG) 1524f0ae7da4SStefano 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); 1525f26d0771SStefano Zampini #endif 1526f26d0771SStefano Zampini ierr = PetscMalloc1(nrg,&idxs);CHKERRQ(ierr); 1527f26d0771SStefano Zampini /* map from [0,nrl) to row */ 1528f26d0771SStefano Zampini for (i=0;i<nrl;i++) idxs[i] = rl[i]; 1529f26d0771SStefano Zampini #if defined(PETSC_USE_DEBUG) 1530f26d0771SStefano Zampini for (i=nrl;i<nrg;i++) idxs[i] = nrg; 1531f26d0771SStefano Zampini #else 1532f26d0771SStefano Zampini for (i=nrl;i<nrg;i++) idxs[i] = -1; 1533f26d0771SStefano Zampini #endif 1534f26d0771SStefano Zampini ierr = ISRestoreIndices(row,&rl);CHKERRQ(ierr); 1535f26d0771SStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(A->rmap->mapping,&rg);CHKERRQ(ierr); 1536f26d0771SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)A),nrg,idxs,PETSC_OWN_POINTER,&is);CHKERRQ(ierr); 1537f26d0771SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is,&rl2g);CHKERRQ(ierr); 1538f26d0771SStefano Zampini ierr = ISDestroy(&is);CHKERRQ(ierr); 1539f26d0771SStefano Zampini /* compute new l2g map for columns */ 1540f26d0771SStefano Zampini if (col != row || A->rmap->mapping != A->cmap->mapping) { 1541f26d0771SStefano Zampini const PetscInt *cg,*cl; 1542f26d0771SStefano Zampini PetscInt ncg; 1543f26d0771SStefano Zampini PetscInt ncl; 1544f26d0771SStefano Zampini 1545f26d0771SStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(A->cmap->mapping,&cg);CHKERRQ(ierr); 1546f26d0771SStefano Zampini ierr = ISGetLocalSize(col,&ncl);CHKERRQ(ierr); 1547f26d0771SStefano Zampini ierr = ISGetIndices(col,&cl);CHKERRQ(ierr); 1548f26d0771SStefano Zampini ierr = ISLocalToGlobalMappingGetSize(A->cmap->mapping,&ncg);CHKERRQ(ierr); 1549f26d0771SStefano Zampini #if defined(PETSC_USE_DEBUG) 1550f0ae7da4SStefano 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); 1551f26d0771SStefano Zampini #endif 1552f26d0771SStefano Zampini ierr = PetscMalloc1(ncg,&idxs);CHKERRQ(ierr); 1553f26d0771SStefano Zampini /* map from [0,ncl) to col */ 1554f26d0771SStefano Zampini for (i=0;i<ncl;i++) idxs[i] = cl[i]; 1555f26d0771SStefano Zampini #if defined(PETSC_USE_DEBUG) 1556f26d0771SStefano Zampini for (i=ncl;i<ncg;i++) idxs[i] = ncg; 1557f26d0771SStefano Zampini #else 1558f26d0771SStefano Zampini for (i=ncl;i<ncg;i++) idxs[i] = -1; 1559f26d0771SStefano Zampini #endif 1560f26d0771SStefano Zampini ierr = ISRestoreIndices(col,&cl);CHKERRQ(ierr); 1561f26d0771SStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(A->cmap->mapping,&cg);CHKERRQ(ierr); 1562f26d0771SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)A),ncg,idxs,PETSC_OWN_POINTER,&is);CHKERRQ(ierr); 1563f26d0771SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is,&cl2g);CHKERRQ(ierr); 1564f26d0771SStefano Zampini ierr = ISDestroy(&is);CHKERRQ(ierr); 1565f26d0771SStefano Zampini } else { 1566f26d0771SStefano Zampini ierr = PetscObjectReference((PetscObject)rl2g);CHKERRQ(ierr); 1567f26d0771SStefano Zampini cl2g = rl2g; 1568f26d0771SStefano Zampini } 1569f26d0771SStefano Zampini /* create the MATIS submatrix */ 1570f26d0771SStefano Zampini ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr); 1571f26d0771SStefano Zampini ierr = MatCreate(PetscObjectComm((PetscObject)A),submat);CHKERRQ(ierr); 1572f26d0771SStefano Zampini ierr = MatSetSizes(*submat,PETSC_DECIDE,PETSC_DECIDE,M,N);CHKERRQ(ierr); 1573f26d0771SStefano Zampini ierr = MatSetType(*submat,MATIS);CHKERRQ(ierr); 1574b0aa3428SStefano Zampini matis = (Mat_IS*)((*submat)->data); 1575f26d0771SStefano Zampini matis->islocalref = PETSC_TRUE; 1576f26d0771SStefano Zampini ierr = MatSetLocalToGlobalMapping(*submat,rl2g,cl2g);CHKERRQ(ierr); 1577f26d0771SStefano Zampini ierr = MatISGetLocalMat(A,&lA);CHKERRQ(ierr); 1578f26d0771SStefano Zampini ierr = MatISSetLocalMat(*submat,lA);CHKERRQ(ierr); 1579f26d0771SStefano Zampini ierr = MatSetUp(*submat);CHKERRQ(ierr); 1580f26d0771SStefano Zampini ierr = MatAssemblyBegin(*submat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1581f26d0771SStefano Zampini ierr = MatAssemblyEnd(*submat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1582f26d0771SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&rl2g);CHKERRQ(ierr); 1583f26d0771SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&cl2g);CHKERRQ(ierr); 1584f26d0771SStefano Zampini /* remove unsupported ops */ 1585f26d0771SStefano Zampini ierr = PetscMemzero((*submat)->ops,sizeof(struct _MatOps));CHKERRQ(ierr); 1586f26d0771SStefano Zampini (*submat)->ops->destroy = MatDestroy_IS; 1587f26d0771SStefano Zampini (*submat)->ops->setvalueslocal = MatSetValuesLocal_SubMat_IS; 1588f26d0771SStefano Zampini (*submat)->ops->setvaluesblockedlocal = MatSetValuesBlockedLocal_SubMat_IS; 1589f26d0771SStefano Zampini (*submat)->ops->assemblybegin = MatAssemblyBegin_IS; 1590f26d0771SStefano Zampini (*submat)->ops->assemblyend = MatAssemblyEnd_IS; 1591f26d0771SStefano Zampini PetscFunctionReturn(0); 1592f26d0771SStefano Zampini } 1593f26d0771SStefano Zampini 1594f26d0771SStefano Zampini #undef __FUNCT__ 1595284134d9SBarry Smith #define __FUNCT__ "MatCreateIS" 1596284134d9SBarry Smith /*@ 15973c212e90SHong Zhang MatCreateIS - Creates a "process" unassembled matrix, assembled on each 1598284134d9SBarry Smith process but not across processes. 1599284134d9SBarry Smith 1600284134d9SBarry Smith Input Parameters: 1601284134d9SBarry Smith + comm - MPI communicator that will share the matrix 1602e176bc59SStefano Zampini . bs - block size of the matrix 1603df3898eeSBarry Smith . m,n,M,N - local and/or global sizes of the left and right vector used in matrix vector products 1604e176bc59SStefano Zampini . rmap - local to global map for rows 1605e176bc59SStefano Zampini - cmap - local to global map for cols 1606284134d9SBarry Smith 1607284134d9SBarry Smith Output Parameter: 1608284134d9SBarry Smith . A - the resulting matrix 1609284134d9SBarry Smith 16108e6c10adSSatish Balay Level: advanced 16118e6c10adSSatish Balay 16123c212e90SHong Zhang Notes: See MATIS for more details. 16136fdf41d1SStefano Zampini m and n are NOT related to the size of the map; they represent the size of the local parts of the vectors 16146fdf41d1SStefano Zampini used in MatMult operations. The sizes of rmap and cmap define the size of the local matrices. 16153c212e90SHong Zhang If either rmap or cmap are NULL, then the matrix is assumed to be square. 1616284134d9SBarry Smith 1617284134d9SBarry Smith .seealso: MATIS, MatSetLocalToGlobalMapping() 1618284134d9SBarry Smith @*/ 1619e176bc59SStefano Zampini PetscErrorCode MatCreateIS(MPI_Comm comm,PetscInt bs,PetscInt m,PetscInt n,PetscInt M,PetscInt N,ISLocalToGlobalMapping rmap,ISLocalToGlobalMapping cmap,Mat *A) 1620284134d9SBarry Smith { 1621284134d9SBarry Smith PetscErrorCode ierr; 1622284134d9SBarry Smith 1623284134d9SBarry Smith PetscFunctionBegin; 16246fdf41d1SStefano Zampini if (!rmap && !cmap) SETERRQ(comm,PETSC_ERR_USER,"You need to provide at least one of the mappings"); 1625284134d9SBarry Smith ierr = MatCreate(comm,A);CHKERRQ(ierr); 16266fdf41d1SStefano Zampini if (bs > 0) { 1627d3ee2243SStefano Zampini ierr = MatSetBlockSize(*A,bs);CHKERRQ(ierr); 16286fdf41d1SStefano Zampini } 1629284134d9SBarry Smith ierr = MatSetSizes(*A,m,n,M,N);CHKERRQ(ierr); 1630284134d9SBarry Smith ierr = MatSetType(*A,MATIS);CHKERRQ(ierr); 1631e176bc59SStefano Zampini if (rmap && cmap) { 1632e176bc59SStefano Zampini ierr = MatSetLocalToGlobalMapping(*A,rmap,cmap);CHKERRQ(ierr); 1633e176bc59SStefano Zampini } else if (!rmap) { 1634e176bc59SStefano Zampini ierr = MatSetLocalToGlobalMapping(*A,cmap,cmap);CHKERRQ(ierr); 1635e176bc59SStefano Zampini } else { 1636e176bc59SStefano Zampini ierr = MatSetLocalToGlobalMapping(*A,rmap,rmap);CHKERRQ(ierr); 1637e176bc59SStefano Zampini } 1638284134d9SBarry Smith PetscFunctionReturn(0); 1639284134d9SBarry Smith } 1640284134d9SBarry Smith 1641b4319ba4SBarry Smith /*MC 1642f26d0771SStefano Zampini MATIS - MATIS = "is" - A matrix type to be used for using the non-overlapping domain decomposition methods (e.g. PCBDDC or KSPFETIDP). 1643b4319ba4SBarry Smith This stores the matrices in globally unassembled form. Each processor 1644b4319ba4SBarry Smith assembles only its local Neumann problem and the parallel matrix vector 1645b4319ba4SBarry Smith product is handled "implicitly". 1646b4319ba4SBarry Smith 1647b4319ba4SBarry Smith Operations Provided: 16486726f965SBarry Smith + MatMult() 16492e74eeadSLisandro Dalcin . MatMultAdd() 16502e74eeadSLisandro Dalcin . MatMultTranspose() 16512e74eeadSLisandro Dalcin . MatMultTransposeAdd() 16526726f965SBarry Smith . MatZeroEntries() 16536726f965SBarry Smith . MatSetOption() 16542e74eeadSLisandro Dalcin . MatZeroRows() 16552e74eeadSLisandro Dalcin . MatSetValues() 165697563a80SStefano Zampini . MatSetValuesBlocked() 16576726f965SBarry Smith . MatSetValuesLocal() 165897563a80SStefano Zampini . MatSetValuesBlockedLocal() 16592e74eeadSLisandro Dalcin . MatScale() 16602e74eeadSLisandro Dalcin . MatGetDiagonal() 16612b404112SStefano Zampini . MatMissingDiagonal() 16622b404112SStefano Zampini . MatDuplicate() 16632b404112SStefano Zampini . MatCopy() 1664f26d0771SStefano Zampini . MatAXPY() 1665f26d0771SStefano Zampini . MatGetSubMatrix() 1666f26d0771SStefano Zampini . MatGetLocalSubMatrix() 1667d7f69cd0SStefano Zampini . MatTranspose() 16686726f965SBarry Smith - MatSetLocalToGlobalMapping() 1669b4319ba4SBarry Smith 1670b4319ba4SBarry Smith Options Database Keys: 1671b4319ba4SBarry Smith . -mat_type is - sets the matrix type to "is" during a call to MatSetFromOptions() 1672b4319ba4SBarry Smith 1673b4319ba4SBarry Smith Notes: Options prefix for the inner matrix are given by -is_mat_xxx 1674b4319ba4SBarry Smith 1675b4319ba4SBarry Smith You must call MatSetLocalToGlobalMapping() before using this matrix type. 1676b4319ba4SBarry Smith 1677b4319ba4SBarry Smith You can do matrix preallocation on the local matrix after you obtain it with 1678eb82efa4SStefano Zampini MatISGetLocalMat(); otherwise, you could use MatISSetPreallocation() 1679b4319ba4SBarry Smith 1680b4319ba4SBarry Smith Level: advanced 1681b4319ba4SBarry Smith 1682f26d0771SStefano Zampini .seealso: Mat, MatISGetLocalMat(), MatSetLocalToGlobalMapping(), MatISSetPreallocation(), MatCreateIS(), PCBDDC, KSPFETIDP 1683b4319ba4SBarry Smith 1684b4319ba4SBarry Smith M*/ 1685b4319ba4SBarry Smith 1686b4319ba4SBarry Smith #undef __FUNCT__ 1687b4319ba4SBarry Smith #define __FUNCT__ "MatCreate_IS" 16888cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatCreate_IS(Mat A) 1689b4319ba4SBarry Smith { 1690dfbe8321SBarry Smith PetscErrorCode ierr; 1691b4319ba4SBarry Smith Mat_IS *b; 1692b4319ba4SBarry Smith 1693b4319ba4SBarry Smith PetscFunctionBegin; 1694b00a9115SJed Brown ierr = PetscNewLog(A,&b);CHKERRQ(ierr); 1695b4319ba4SBarry Smith A->data = (void*)b; 1696b4319ba4SBarry Smith 1697e176bc59SStefano Zampini /* matrix ops */ 1698e176bc59SStefano Zampini ierr = PetscMemzero(A->ops,sizeof(struct _MatOps));CHKERRQ(ierr); 1699b4319ba4SBarry Smith A->ops->mult = MatMult_IS; 17002e74eeadSLisandro Dalcin A->ops->multadd = MatMultAdd_IS; 17012e74eeadSLisandro Dalcin A->ops->multtranspose = MatMultTranspose_IS; 17022e74eeadSLisandro Dalcin A->ops->multtransposeadd = MatMultTransposeAdd_IS; 1703b4319ba4SBarry Smith A->ops->destroy = MatDestroy_IS; 1704b4319ba4SBarry Smith A->ops->setlocaltoglobalmapping = MatSetLocalToGlobalMapping_IS; 17052e74eeadSLisandro Dalcin A->ops->setvalues = MatSetValues_IS; 170698921651SStefano Zampini A->ops->setvaluesblocked = MatSetValuesBlocked_IS; 1707b4319ba4SBarry Smith A->ops->setvalueslocal = MatSetValuesLocal_IS; 1708f0006bf2SLisandro Dalcin A->ops->setvaluesblockedlocal = MatSetValuesBlockedLocal_IS; 17092e74eeadSLisandro Dalcin A->ops->zerorows = MatZeroRows_IS; 1710f0ae7da4SStefano Zampini A->ops->zerorowscolumns = MatZeroRowsColumns_IS; 1711b4319ba4SBarry Smith A->ops->assemblybegin = MatAssemblyBegin_IS; 1712b4319ba4SBarry Smith A->ops->assemblyend = MatAssemblyEnd_IS; 1713b4319ba4SBarry Smith A->ops->view = MatView_IS; 17146726f965SBarry Smith A->ops->zeroentries = MatZeroEntries_IS; 17152e74eeadSLisandro Dalcin A->ops->scale = MatScale_IS; 17162e74eeadSLisandro Dalcin A->ops->getdiagonal = MatGetDiagonal_IS; 17176726f965SBarry Smith A->ops->setoption = MatSetOption_IS; 171869796d55SStefano Zampini A->ops->ishermitian = MatIsHermitian_IS; 171969796d55SStefano Zampini A->ops->issymmetric = MatIsSymmetric_IS; 1720ad6194a2SStefano Zampini A->ops->duplicate = MatDuplicate_IS; 17216bd84002SStefano Zampini A->ops->missingdiagonal = MatMissingDiagonal_IS; 17222b404112SStefano Zampini A->ops->copy = MatCopy_IS; 1723659959c5SStefano Zampini A->ops->getlocalsubmatrix = MatGetLocalSubMatrix_IS; 1724a8116848SStefano Zampini A->ops->getsubmatrix = MatGetSubMatrix_IS; 1725f26d0771SStefano Zampini A->ops->axpy = MatAXPY_IS; 17263fd1c9e7SStefano Zampini A->ops->diagonalset = MatDiagonalSet_IS; 17273fd1c9e7SStefano Zampini A->ops->shift = MatShift_IS; 1728d7f69cd0SStefano Zampini A->ops->transpose = MatTranspose_IS; 1729b4319ba4SBarry Smith 1730b7ce53b6SStefano Zampini /* special MATIS functions */ 1731bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatISGetLocalMat_C",MatISGetLocalMat_IS);CHKERRQ(ierr); 1732bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatISSetLocalMat_C",MatISSetLocalMat_IS);CHKERRQ(ierr); 1733b7ce53b6SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatISGetMPIXAIJ_C",MatISGetMPIXAIJ_IS);CHKERRQ(ierr); 17342e1947a5SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatISSetPreallocation_C",MatISSetPreallocation_IS);CHKERRQ(ierr); 173517667f90SBarry Smith ierr = PetscObjectChangeTypeName((PetscObject)A,MATIS);CHKERRQ(ierr); 1736b4319ba4SBarry Smith PetscFunctionReturn(0); 1737b4319ba4SBarry Smith } 1738