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__ 177fa8f2d3SStefano Zampini #define __FUNCT__ "MatGetInfo_IS" 187fa8f2d3SStefano Zampini static PetscErrorCode MatGetInfo_IS(Mat A,MatInfoType flag,MatInfo *ginfo) 197fa8f2d3SStefano Zampini { 207fa8f2d3SStefano Zampini Mat_IS *matis = (Mat_IS*)A->data; 217fa8f2d3SStefano Zampini MatInfo info; 22*314ce898Sstefano_zampini PetscReal isend[6],irecv[6]; 237fa8f2d3SStefano Zampini PetscInt bs; 247fa8f2d3SStefano Zampini PetscErrorCode ierr; 257fa8f2d3SStefano Zampini 267fa8f2d3SStefano Zampini PetscFunctionBegin; 277fa8f2d3SStefano Zampini ierr = MatGetBlockSize(A,&bs);CHKERRQ(ierr); 287fa8f2d3SStefano Zampini ierr = MatGetInfo(matis->A,MAT_LOCAL,&info);CHKERRQ(ierr); 297fa8f2d3SStefano Zampini isend[0] = info.nz_used; 307fa8f2d3SStefano Zampini isend[1] = info.nz_allocated; 317fa8f2d3SStefano Zampini isend[2] = info.nz_unneeded; 327fa8f2d3SStefano Zampini isend[3] = info.memory; 337fa8f2d3SStefano Zampini isend[4] = info.mallocs; 34*314ce898Sstefano_zampini isend[5] = matis->A->num_ass; 357fa8f2d3SStefano Zampini if (flag == MAT_LOCAL) { 367fa8f2d3SStefano Zampini ginfo->nz_used = isend[0]; 377fa8f2d3SStefano Zampini ginfo->nz_allocated = isend[1]; 387fa8f2d3SStefano Zampini ginfo->nz_unneeded = isend[2]; 397fa8f2d3SStefano Zampini ginfo->memory = isend[3]; 407fa8f2d3SStefano Zampini ginfo->mallocs = isend[4]; 41*314ce898Sstefano_zampini ginfo->assemblies = isend[5]; 427fa8f2d3SStefano Zampini } else if (flag == MAT_GLOBAL_MAX) { 43*314ce898Sstefano_zampini ierr = MPIU_Allreduce(isend,irecv,6,MPIU_REAL,MPIU_MAX,PetscObjectComm((PetscObject)A));CHKERRQ(ierr); 447fa8f2d3SStefano Zampini 457fa8f2d3SStefano Zampini ginfo->nz_used = irecv[0]; 467fa8f2d3SStefano Zampini ginfo->nz_allocated = irecv[1]; 477fa8f2d3SStefano Zampini ginfo->nz_unneeded = irecv[2]; 487fa8f2d3SStefano Zampini ginfo->memory = irecv[3]; 497fa8f2d3SStefano Zampini ginfo->mallocs = irecv[4]; 50*314ce898Sstefano_zampini ginfo->assemblies = irecv[5]; 517fa8f2d3SStefano Zampini } else if (flag == MAT_GLOBAL_SUM) { 527fa8f2d3SStefano Zampini ierr = MPIU_Allreduce(isend,irecv,5,MPIU_REAL,MPIU_SUM,PetscObjectComm((PetscObject)A));CHKERRQ(ierr); 537fa8f2d3SStefano Zampini 547fa8f2d3SStefano Zampini ginfo->nz_used = irecv[0]; 557fa8f2d3SStefano Zampini ginfo->nz_allocated = irecv[1]; 567fa8f2d3SStefano Zampini ginfo->nz_unneeded = irecv[2]; 577fa8f2d3SStefano Zampini ginfo->memory = irecv[3]; 587fa8f2d3SStefano Zampini ginfo->mallocs = irecv[4]; 597fa8f2d3SStefano Zampini ginfo->assemblies = A->num_ass; 607fa8f2d3SStefano Zampini } 617fa8f2d3SStefano Zampini ginfo->block_size = bs; 627fa8f2d3SStefano Zampini ginfo->fill_ratio_given = 0; 637fa8f2d3SStefano Zampini ginfo->fill_ratio_needed = 0; 647fa8f2d3SStefano Zampini ginfo->factor_mallocs = 0; 657fa8f2d3SStefano Zampini PetscFunctionReturn(0); 667fa8f2d3SStefano Zampini } 677fa8f2d3SStefano Zampini 687fa8f2d3SStefano Zampini #undef __FUNCT__ 69d7f69cd0SStefano Zampini #define __FUNCT__ "MatTranspose_IS" 70d7f69cd0SStefano Zampini PetscErrorCode MatTranspose_IS(Mat A,MatReuse reuse,Mat *B) 71d7f69cd0SStefano Zampini { 72d7f69cd0SStefano Zampini Mat C,lC,lA; 73d7f69cd0SStefano Zampini ISLocalToGlobalMapping rl2g,cl2g; 74d7f69cd0SStefano Zampini PetscBool notset = PETSC_FALSE,cong = PETSC_TRUE; 75d7f69cd0SStefano Zampini PetscErrorCode ierr; 76d7f69cd0SStefano Zampini 77d7f69cd0SStefano Zampini PetscFunctionBegin; 78d7f69cd0SStefano Zampini if (reuse == MAT_REUSE_MATRIX) { 79d7f69cd0SStefano Zampini PetscBool rcong,ccong; 80d7f69cd0SStefano Zampini 81d7f69cd0SStefano Zampini ierr = PetscLayoutCompare((*B)->cmap,A->rmap,&rcong);CHKERRQ(ierr); 82d7f69cd0SStefano Zampini ierr = PetscLayoutCompare((*B)->rmap,A->cmap,&ccong);CHKERRQ(ierr); 83fa520230SStefano Zampini cong = (PetscBool)(rcong || ccong); 84d7f69cd0SStefano Zampini } 85d7f69cd0SStefano Zampini if (reuse == MAT_INITIAL_MATRIX || *B == A || !cong) { 86d7f69cd0SStefano Zampini ierr = MatCreate(PetscObjectComm((PetscObject)A),&C);CHKERRQ(ierr); 87d7f69cd0SStefano Zampini } else { 88d7f69cd0SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)*B,MATIS,¬set);CHKERRQ(ierr); 89d7f69cd0SStefano Zampini C = *B; 90d7f69cd0SStefano Zampini } 91d7f69cd0SStefano Zampini 92d7f69cd0SStefano Zampini if (!notset) { 93d7f69cd0SStefano Zampini ierr = MatSetSizes(C,A->cmap->n,A->rmap->n,A->cmap->N,A->rmap->N);CHKERRQ(ierr); 94d7f69cd0SStefano Zampini ierr = MatSetBlockSizes(C,PetscAbs(A->cmap->bs),PetscAbs(A->rmap->bs));CHKERRQ(ierr); 95d7f69cd0SStefano Zampini ierr = MatSetType(C,MATIS);CHKERRQ(ierr); 96d7f69cd0SStefano Zampini ierr = MatGetLocalToGlobalMapping(A,&rl2g,&cl2g);CHKERRQ(ierr); 97d7f69cd0SStefano Zampini ierr = MatSetLocalToGlobalMapping(C,cl2g,rl2g);CHKERRQ(ierr); 98d7f69cd0SStefano Zampini } 99d7f69cd0SStefano Zampini 100d7f69cd0SStefano Zampini /* perform local transposition */ 101d7f69cd0SStefano Zampini ierr = MatISGetLocalMat(A,&lA);CHKERRQ(ierr); 102d7f69cd0SStefano Zampini ierr = MatTranspose(lA,MAT_INITIAL_MATRIX,&lC);CHKERRQ(ierr); 103d7f69cd0SStefano Zampini ierr = MatISSetLocalMat(C,lC);CHKERRQ(ierr); 104d7f69cd0SStefano Zampini ierr = MatDestroy(&lC);CHKERRQ(ierr); 105d7f69cd0SStefano Zampini 106d7f69cd0SStefano Zampini ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 107d7f69cd0SStefano Zampini ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 108d7f69cd0SStefano Zampini 109d7f69cd0SStefano Zampini if (reuse == MAT_INITIAL_MATRIX || *B != A) { 110d7f69cd0SStefano Zampini if (!cong) { 111d7f69cd0SStefano Zampini ierr = MatDestroy(B);CHKERRQ(ierr); 112d7f69cd0SStefano Zampini } 113d7f69cd0SStefano Zampini *B = C; 114d7f69cd0SStefano Zampini } else { 115d7f69cd0SStefano Zampini ierr = MatHeaderMerge(A,&C);CHKERRQ(ierr); 116d7f69cd0SStefano Zampini } 117d7f69cd0SStefano Zampini PetscFunctionReturn(0); 118d7f69cd0SStefano Zampini } 119d7f69cd0SStefano Zampini 120d7f69cd0SStefano Zampini #undef __FUNCT__ 1213fd1c9e7SStefano Zampini #define __FUNCT__ "MatDiagonalSet_IS" 1223fd1c9e7SStefano Zampini PetscErrorCode MatDiagonalSet_IS(Mat A,Vec D,InsertMode insmode) 1233fd1c9e7SStefano Zampini { 1243fd1c9e7SStefano Zampini Mat_IS *is = (Mat_IS*)A->data; 1253fd1c9e7SStefano Zampini PetscErrorCode ierr; 1263fd1c9e7SStefano Zampini 1273fd1c9e7SStefano Zampini PetscFunctionBegin; 1283fd1c9e7SStefano Zampini if (!D) { /* this code branch is used by MatShift_IS */ 1293fd1c9e7SStefano Zampini ierr = VecSet(is->y,1.);CHKERRQ(ierr); 1303fd1c9e7SStefano Zampini } else { 1313fd1c9e7SStefano Zampini ierr = VecScatterBegin(is->rctx,D,is->y,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1323fd1c9e7SStefano Zampini ierr = VecScatterEnd(is->rctx,D,is->y,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1333fd1c9e7SStefano Zampini } 1343fd1c9e7SStefano Zampini ierr = VecPointwiseDivide(is->y,is->y,is->counter);CHKERRQ(ierr); 1353fd1c9e7SStefano Zampini ierr = MatDiagonalSet(is->A,is->y,insmode);CHKERRQ(ierr); 1363fd1c9e7SStefano Zampini PetscFunctionReturn(0); 1373fd1c9e7SStefano Zampini } 1383fd1c9e7SStefano Zampini 1393fd1c9e7SStefano Zampini #undef __FUNCT__ 1403fd1c9e7SStefano Zampini #define __FUNCT__ "MatShift_IS" 1413fd1c9e7SStefano Zampini PetscErrorCode MatShift_IS(Mat A,PetscScalar a) 1423fd1c9e7SStefano Zampini { 1433fd1c9e7SStefano Zampini PetscErrorCode ierr; 1443fd1c9e7SStefano Zampini 1453fd1c9e7SStefano Zampini PetscFunctionBegin; 1463fd1c9e7SStefano Zampini ierr = MatDiagonalSet_IS(A,NULL,ADD_VALUES);CHKERRQ(ierr); 1473fd1c9e7SStefano Zampini PetscFunctionReturn(0); 1483fd1c9e7SStefano Zampini } 1493fd1c9e7SStefano Zampini 1503fd1c9e7SStefano Zampini #undef __FUNCT__ 151f26d0771SStefano Zampini #define __FUNCT__ "MatSetValuesLocal_SubMat_IS" 152f26d0771SStefano Zampini static PetscErrorCode MatSetValuesLocal_SubMat_IS(Mat A,PetscInt m,const PetscInt *rows, PetscInt n,const PetscInt *cols,const PetscScalar *values,InsertMode addv) 153f26d0771SStefano Zampini { 154f26d0771SStefano Zampini PetscErrorCode ierr; 155f26d0771SStefano Zampini Mat_IS *is = (Mat_IS*)A->data; 156f26d0771SStefano Zampini PetscInt rows_l[MATIS_MAX_ENTRIES_INSERTION],cols_l[MATIS_MAX_ENTRIES_INSERTION]; 157f26d0771SStefano Zampini 158f26d0771SStefano Zampini PetscFunctionBegin; 159f26d0771SStefano Zampini #if defined(PETSC_USE_DEBUG) 160f26d0771SStefano 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); 161f26d0771SStefano Zampini #endif 162f26d0771SStefano Zampini ierr = ISLocalToGlobalMappingApply(A->rmap->mapping,m,rows,rows_l);CHKERRQ(ierr); 163f26d0771SStefano Zampini ierr = ISLocalToGlobalMappingApply(A->cmap->mapping,n,cols,cols_l);CHKERRQ(ierr); 164f26d0771SStefano Zampini ierr = MatSetValues(is->A,m,rows_l,n,cols_l,values,addv);CHKERRQ(ierr); 165f26d0771SStefano Zampini PetscFunctionReturn(0); 166f26d0771SStefano Zampini } 167f26d0771SStefano Zampini 168f26d0771SStefano Zampini #undef __FUNCT__ 169f26d0771SStefano Zampini #define __FUNCT__ "MatSetValuesBlockedLocal_SubMat_IS" 170f26d0771SStefano Zampini static PetscErrorCode MatSetValuesBlockedLocal_SubMat_IS(Mat A,PetscInt m,const PetscInt *rows, PetscInt n,const PetscInt *cols,const PetscScalar *values,InsertMode addv) 171f26d0771SStefano Zampini { 172f26d0771SStefano Zampini PetscErrorCode ierr; 173f26d0771SStefano Zampini Mat_IS *is = (Mat_IS*)A->data; 174f26d0771SStefano Zampini PetscInt rows_l[MATIS_MAX_ENTRIES_INSERTION],cols_l[MATIS_MAX_ENTRIES_INSERTION]; 175f26d0771SStefano Zampini 176f26d0771SStefano Zampini PetscFunctionBegin; 177f26d0771SStefano Zampini #if defined(PETSC_USE_DEBUG) 178f26d0771SStefano 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); 179f26d0771SStefano Zampini #endif 180f26d0771SStefano Zampini ierr = ISLocalToGlobalMappingApplyBlock(A->rmap->mapping,m,rows,rows_l);CHKERRQ(ierr); 181f26d0771SStefano Zampini ierr = ISLocalToGlobalMappingApplyBlock(A->cmap->mapping,n,cols,cols_l);CHKERRQ(ierr); 182f26d0771SStefano Zampini ierr = MatSetValuesBlocked(is->A,m,rows_l,n,cols_l,values,addv);CHKERRQ(ierr); 183f26d0771SStefano Zampini PetscFunctionReturn(0); 184f26d0771SStefano Zampini } 185f26d0771SStefano Zampini 186f26d0771SStefano Zampini #undef __FUNCT__ 187a8116848SStefano Zampini #define __FUNCT__ "PetscLayoutMapLocal_Private" 188f0ae7da4SStefano Zampini static PetscErrorCode PetscLayoutMapLocal_Private(PetscLayout map,PetscInt N,const PetscInt idxs[], PetscInt *on,PetscInt **oidxs,PetscInt **ogidxs) 189a8116848SStefano Zampini { 190a8116848SStefano Zampini PetscInt *owners = map->range; 191a8116848SStefano Zampini PetscInt n = map->n; 192a8116848SStefano Zampini PetscSF sf; 193a8116848SStefano Zampini PetscInt *lidxs,*work = NULL; 194a8116848SStefano Zampini PetscSFNode *ridxs; 195a8116848SStefano Zampini PetscMPIInt rank; 196a8116848SStefano Zampini PetscInt r, p = 0, len = 0; 197a8116848SStefano Zampini PetscErrorCode ierr; 198a8116848SStefano Zampini 199a8116848SStefano Zampini PetscFunctionBegin; 200a8116848SStefano Zampini /* Create SF where leaves are input idxs and roots are owned idxs (code adapted from MatZeroRowsMapLocal_Private) */ 201a8116848SStefano Zampini ierr = MPI_Comm_rank(map->comm,&rank);CHKERRQ(ierr); 202a8116848SStefano Zampini ierr = PetscMalloc1(n,&lidxs);CHKERRQ(ierr); 203a8116848SStefano Zampini for (r = 0; r < n; ++r) lidxs[r] = -1; 204a8116848SStefano Zampini ierr = PetscMalloc1(N,&ridxs);CHKERRQ(ierr); 205a8116848SStefano Zampini for (r = 0; r < N; ++r) { 206a8116848SStefano Zampini const PetscInt idx = idxs[r]; 207a8116848SStefano 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); 208a8116848SStefano Zampini if (idx < owners[p] || owners[p+1] <= idx) { /* short-circuit the search if the last p owns this idx too */ 209a8116848SStefano Zampini ierr = PetscLayoutFindOwner(map,idx,&p);CHKERRQ(ierr); 210a8116848SStefano Zampini } 211a8116848SStefano Zampini ridxs[r].rank = p; 212a8116848SStefano Zampini ridxs[r].index = idxs[r] - owners[p]; 213a8116848SStefano Zampini } 214a8116848SStefano Zampini ierr = PetscSFCreate(map->comm,&sf);CHKERRQ(ierr); 215a8116848SStefano Zampini ierr = PetscSFSetGraph(sf,n,N,NULL,PETSC_OWN_POINTER,ridxs,PETSC_OWN_POINTER);CHKERRQ(ierr); 216a8116848SStefano Zampini ierr = PetscSFReduceBegin(sf,MPIU_INT,(PetscInt*)idxs,lidxs,MPI_LOR);CHKERRQ(ierr); 217a8116848SStefano Zampini ierr = PetscSFReduceEnd(sf,MPIU_INT,(PetscInt*)idxs,lidxs,MPI_LOR);CHKERRQ(ierr); 218f0ae7da4SStefano Zampini if (ogidxs) { /* communicate global idxs */ 219a8116848SStefano Zampini PetscInt cum = 0,start,*work2; 220f0ae7da4SStefano Zampini 221f0ae7da4SStefano Zampini ierr = PetscMalloc1(n,&work);CHKERRQ(ierr); 222a8116848SStefano Zampini ierr = PetscCalloc1(N,&work2);CHKERRQ(ierr); 223a8116848SStefano Zampini for (r = 0; r < N; ++r) if (idxs[r] >=0) cum++; 224a8116848SStefano Zampini ierr = MPI_Scan(&cum,&start,1,MPIU_INT,MPI_SUM,map->comm);CHKERRQ(ierr); 225a8116848SStefano Zampini start -= cum; 226a8116848SStefano Zampini cum = 0; 227a8116848SStefano Zampini for (r = 0; r < N; ++r) if (idxs[r] >=0) work2[r] = start+cum++; 228a8116848SStefano Zampini ierr = PetscSFReduceBegin(sf,MPIU_INT,work2,work,MPIU_REPLACE);CHKERRQ(ierr); 229a8116848SStefano Zampini ierr = PetscSFReduceEnd(sf,MPIU_INT,work2,work,MPIU_REPLACE);CHKERRQ(ierr); 230a8116848SStefano Zampini ierr = PetscFree(work2);CHKERRQ(ierr); 231a8116848SStefano Zampini } 232a8116848SStefano Zampini ierr = PetscSFDestroy(&sf);CHKERRQ(ierr); 233a8116848SStefano Zampini /* Compress and put in indices */ 234a8116848SStefano Zampini for (r = 0; r < n; ++r) 235a8116848SStefano Zampini if (lidxs[r] >= 0) { 236a8116848SStefano Zampini if (work) work[len] = work[r]; 237a8116848SStefano Zampini lidxs[len++] = r; 238a8116848SStefano Zampini } 239a8116848SStefano Zampini if (on) *on = len; 240a8116848SStefano Zampini if (oidxs) *oidxs = lidxs; 241a8116848SStefano Zampini if (ogidxs) *ogidxs = work; 242a8116848SStefano Zampini PetscFunctionReturn(0); 243a8116848SStefano Zampini } 244a8116848SStefano Zampini 245a8116848SStefano Zampini #undef __FUNCT__ 246a8116848SStefano Zampini #define __FUNCT__ "MatGetSubMatrix_IS" 247a8116848SStefano Zampini static PetscErrorCode MatGetSubMatrix_IS(Mat mat,IS irow,IS icol,MatReuse scall,Mat *newmat) 248a8116848SStefano Zampini { 249a8116848SStefano Zampini Mat locmat,newlocmat; 250a8116848SStefano Zampini Mat_IS *newmatis; 251a8116848SStefano Zampini #if defined(PETSC_USE_DEBUG) 252a8116848SStefano Zampini Vec rtest,ltest; 253a8116848SStefano Zampini const PetscScalar *array; 254a8116848SStefano Zampini #endif 255a8116848SStefano Zampini const PetscInt *idxs; 256a8116848SStefano Zampini PetscInt i,m,n; 257a8116848SStefano Zampini PetscErrorCode ierr; 258a8116848SStefano Zampini 259a8116848SStefano Zampini PetscFunctionBegin; 260a8116848SStefano Zampini if (scall == MAT_REUSE_MATRIX) { 261a8116848SStefano Zampini PetscBool ismatis; 262a8116848SStefano Zampini 263a8116848SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)*newmat,MATIS,&ismatis);CHKERRQ(ierr); 264a8116848SStefano Zampini if (!ismatis) SETERRQ(PetscObjectComm((PetscObject)*newmat),PETSC_ERR_ARG_WRONG,"Cannot reuse matrix! Not of MATIS type"); 265a8116848SStefano Zampini newmatis = (Mat_IS*)(*newmat)->data; 266a8116848SStefano Zampini if (!newmatis->getsub_ris) SETERRQ(PetscObjectComm((PetscObject)*newmat),PETSC_ERR_ARG_WRONG,"Cannot reuse matrix! Misses local row IS"); 267a8116848SStefano Zampini if (!newmatis->getsub_cis) SETERRQ(PetscObjectComm((PetscObject)*newmat),PETSC_ERR_ARG_WRONG,"Cannot reuse matrix! Misses local col IS"); 268a8116848SStefano Zampini } 269a8116848SStefano Zampini /* irow and icol may not have duplicate entries */ 270a8116848SStefano Zampini #if defined(PETSC_USE_DEBUG) 271a8116848SStefano Zampini ierr = MatCreateVecs(mat,<est,&rtest);CHKERRQ(ierr); 272a8116848SStefano Zampini ierr = ISGetLocalSize(irow,&n);CHKERRQ(ierr); 273a8116848SStefano Zampini ierr = ISGetIndices(irow,&idxs);CHKERRQ(ierr); 274a8116848SStefano Zampini for (i=0;i<n;i++) { 275a8116848SStefano Zampini ierr = VecSetValue(rtest,idxs[i],1.0,ADD_VALUES);CHKERRQ(ierr); 276a8116848SStefano Zampini } 277a8116848SStefano Zampini ierr = VecAssemblyBegin(rtest);CHKERRQ(ierr); 278a8116848SStefano Zampini ierr = VecAssemblyEnd(rtest);CHKERRQ(ierr); 279a8116848SStefano Zampini ierr = VecGetLocalSize(rtest,&n);CHKERRQ(ierr); 280a8116848SStefano Zampini ierr = VecGetOwnershipRange(rtest,&m,NULL);CHKERRQ(ierr); 281a8116848SStefano Zampini ierr = VecGetArrayRead(rtest,&array);CHKERRQ(ierr); 282fd479f66SMatthew 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])); 283a8116848SStefano Zampini ierr = VecRestoreArrayRead(rtest,&array);CHKERRQ(ierr); 284a8116848SStefano Zampini ierr = ISRestoreIndices(irow,&idxs);CHKERRQ(ierr); 285a8116848SStefano Zampini ierr = ISGetLocalSize(icol,&n);CHKERRQ(ierr); 286a8116848SStefano Zampini ierr = ISGetIndices(icol,&idxs);CHKERRQ(ierr); 287a8116848SStefano Zampini for (i=0;i<n;i++) { 288a8116848SStefano Zampini ierr = VecSetValue(ltest,idxs[i],1.0,ADD_VALUES);CHKERRQ(ierr); 289a8116848SStefano Zampini } 290a8116848SStefano Zampini ierr = VecAssemblyBegin(ltest);CHKERRQ(ierr); 291a8116848SStefano Zampini ierr = VecAssemblyEnd(ltest);CHKERRQ(ierr); 292a8116848SStefano Zampini ierr = VecGetLocalSize(ltest,&n);CHKERRQ(ierr); 293a8116848SStefano Zampini ierr = VecGetOwnershipRange(ltest,&m,NULL);CHKERRQ(ierr); 294a8116848SStefano Zampini ierr = VecGetArrayRead(ltest,&array);CHKERRQ(ierr); 295fd479f66SMatthew 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])); 296a8116848SStefano Zampini ierr = VecRestoreArrayRead(ltest,&array);CHKERRQ(ierr); 297a8116848SStefano Zampini ierr = ISRestoreIndices(icol,&idxs);CHKERRQ(ierr); 298a8116848SStefano Zampini ierr = VecDestroy(&rtest);CHKERRQ(ierr); 299a8116848SStefano Zampini ierr = VecDestroy(<est);CHKERRQ(ierr); 300a8116848SStefano Zampini #endif 301a8116848SStefano Zampini if (scall == MAT_INITIAL_MATRIX) { 302a8116848SStefano Zampini Mat_IS *matis = (Mat_IS*)mat->data; 303a8116848SStefano Zampini ISLocalToGlobalMapping rl2g; 304a8116848SStefano Zampini IS is; 305a8116848SStefano Zampini PetscInt *lidxs,*lgidxs,*newgidxs; 3066dd40735SStefano Zampini PetscInt ll,newloc; 307a8116848SStefano Zampini MPI_Comm comm; 308a8116848SStefano Zampini 309a8116848SStefano Zampini ierr = PetscObjectGetComm((PetscObject)mat,&comm);CHKERRQ(ierr); 310a8116848SStefano Zampini ierr = ISGetLocalSize(irow,&m);CHKERRQ(ierr); 311a8116848SStefano Zampini ierr = ISGetLocalSize(icol,&n);CHKERRQ(ierr); 312a8116848SStefano Zampini ierr = MatCreate(comm,newmat);CHKERRQ(ierr); 313a8116848SStefano Zampini ierr = MatSetType(*newmat,MATIS);CHKERRQ(ierr); 314a8116848SStefano Zampini ierr = MatSetSizes(*newmat,m,n,PETSC_DECIDE,PETSC_DECIDE);CHKERRQ(ierr); 315a8116848SStefano Zampini /* communicate irow to their owners in the layout */ 316a8116848SStefano Zampini ierr = ISGetIndices(irow,&idxs);CHKERRQ(ierr); 317f0ae7da4SStefano Zampini ierr = PetscLayoutMapLocal_Private(mat->rmap,m,idxs,&ll,&lidxs,&lgidxs);CHKERRQ(ierr); 318a8116848SStefano Zampini ierr = ISRestoreIndices(irow,&idxs);CHKERRQ(ierr); 319a8116848SStefano Zampini if (!matis->sf) { /* setup SF if not yet created and allocate rootdata and leafdata */ 320a8116848SStefano Zampini ierr = MatISComputeSF_Private(mat);CHKERRQ(ierr); 321a8116848SStefano Zampini } 322a8116848SStefano Zampini ierr = PetscMemzero(matis->sf_rootdata,matis->sf_nroots*sizeof(PetscInt));CHKERRQ(ierr); 323a8116848SStefano Zampini for (i=0;i<ll;i++) matis->sf_rootdata[lidxs[i]] = lgidxs[i]+1; 324a8116848SStefano Zampini ierr = PetscFree(lidxs);CHKERRQ(ierr); 325a8116848SStefano Zampini ierr = PetscFree(lgidxs);CHKERRQ(ierr); 326a8116848SStefano Zampini ierr = PetscSFBcastBegin(matis->sf,MPIU_INT,matis->sf_rootdata,matis->sf_leafdata);CHKERRQ(ierr); 327a8116848SStefano Zampini ierr = PetscSFBcastEnd(matis->sf,MPIU_INT,matis->sf_rootdata,matis->sf_leafdata);CHKERRQ(ierr); 328a8116848SStefano Zampini for (i=0,newloc=0;i<matis->sf_nleaves;i++) if (matis->sf_leafdata[i]) newloc++; 329a8116848SStefano Zampini ierr = PetscMalloc1(newloc,&newgidxs);CHKERRQ(ierr); 330a8116848SStefano Zampini ierr = PetscMalloc1(newloc,&lidxs);CHKERRQ(ierr); 331a8116848SStefano Zampini for (i=0,newloc=0;i<matis->sf_nleaves;i++) 332a8116848SStefano Zampini if (matis->sf_leafdata[i]) { 333a8116848SStefano Zampini lidxs[newloc] = i; 334a8116848SStefano Zampini newgidxs[newloc++] = matis->sf_leafdata[i]-1; 335a8116848SStefano Zampini } 336a8116848SStefano Zampini ierr = ISCreateGeneral(comm,newloc,newgidxs,PETSC_OWN_POINTER,&is);CHKERRQ(ierr); 337a8116848SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is,&rl2g);CHKERRQ(ierr); 338a8116848SStefano Zampini ierr = ISDestroy(&is);CHKERRQ(ierr); 339a8116848SStefano Zampini /* local is to extract local submatrix */ 340a8116848SStefano Zampini newmatis = (Mat_IS*)(*newmat)->data; 341a8116848SStefano Zampini ierr = ISCreateGeneral(comm,newloc,lidxs,PETSC_OWN_POINTER,&newmatis->getsub_ris);CHKERRQ(ierr); 342a8116848SStefano Zampini if (mat->congruentlayouts == -1) { /* first time we compare rows and cols layouts */ 343a8116848SStefano Zampini PetscBool cong; 344a8116848SStefano Zampini ierr = PetscLayoutCompare(mat->rmap,mat->cmap,&cong);CHKERRQ(ierr); 345a8116848SStefano Zampini if (cong) mat->congruentlayouts = 1; 346a8116848SStefano Zampini else mat->congruentlayouts = 0; 347a8116848SStefano Zampini } 348a8116848SStefano Zampini if (mat->congruentlayouts && irow == icol) { 349a8116848SStefano Zampini ierr = MatSetLocalToGlobalMapping(*newmat,rl2g,rl2g);CHKERRQ(ierr); 350a8116848SStefano Zampini ierr = PetscObjectReference((PetscObject)newmatis->getsub_ris);CHKERRQ(ierr); 351a8116848SStefano Zampini newmatis->getsub_cis = newmatis->getsub_ris; 352a8116848SStefano Zampini } else { 353a8116848SStefano Zampini ISLocalToGlobalMapping cl2g; 354a8116848SStefano Zampini 355a8116848SStefano Zampini /* communicate icol to their owners in the layout */ 356a8116848SStefano Zampini ierr = ISGetIndices(icol,&idxs);CHKERRQ(ierr); 357f0ae7da4SStefano Zampini ierr = PetscLayoutMapLocal_Private(mat->cmap,n,idxs,&ll,&lidxs,&lgidxs);CHKERRQ(ierr); 358a8116848SStefano Zampini ierr = ISRestoreIndices(icol,&idxs);CHKERRQ(ierr); 359a8116848SStefano Zampini ierr = PetscMemzero(matis->csf_rootdata,matis->csf_nroots*sizeof(PetscInt));CHKERRQ(ierr); 360a8116848SStefano Zampini for (i=0;i<ll;i++) matis->csf_rootdata[lidxs[i]] = lgidxs[i]+1; 361a8116848SStefano Zampini ierr = PetscFree(lidxs);CHKERRQ(ierr); 362a8116848SStefano Zampini ierr = PetscFree(lgidxs);CHKERRQ(ierr); 363a8116848SStefano Zampini ierr = PetscSFBcastBegin(matis->csf,MPIU_INT,matis->csf_rootdata,matis->csf_leafdata);CHKERRQ(ierr); 364a8116848SStefano Zampini ierr = PetscSFBcastEnd(matis->csf,MPIU_INT,matis->csf_rootdata,matis->csf_leafdata);CHKERRQ(ierr); 365a8116848SStefano Zampini for (i=0,newloc=0;i<matis->csf_nleaves;i++) if (matis->csf_leafdata[i]) newloc++; 366a8116848SStefano Zampini ierr = PetscMalloc1(newloc,&newgidxs);CHKERRQ(ierr); 367a8116848SStefano Zampini ierr = PetscMalloc1(newloc,&lidxs);CHKERRQ(ierr); 368a8116848SStefano Zampini for (i=0,newloc=0;i<matis->csf_nleaves;i++) 369a8116848SStefano Zampini if (matis->csf_leafdata[i]) { 370a8116848SStefano Zampini lidxs[newloc] = i; 371a8116848SStefano Zampini newgidxs[newloc++] = matis->csf_leafdata[i]-1; 372a8116848SStefano Zampini } 373a8116848SStefano Zampini ierr = ISCreateGeneral(comm,newloc,newgidxs,PETSC_OWN_POINTER,&is);CHKERRQ(ierr); 374a8116848SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is,&cl2g);CHKERRQ(ierr); 375a8116848SStefano Zampini ierr = ISDestroy(&is);CHKERRQ(ierr); 376a8116848SStefano Zampini /* local is to extract local submatrix */ 377a8116848SStefano Zampini ierr = ISCreateGeneral(comm,newloc,lidxs,PETSC_OWN_POINTER,&newmatis->getsub_cis);CHKERRQ(ierr); 378a8116848SStefano Zampini ierr = MatSetLocalToGlobalMapping(*newmat,rl2g,cl2g);CHKERRQ(ierr); 379a8116848SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&cl2g);CHKERRQ(ierr); 380a8116848SStefano Zampini } 381a8116848SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&rl2g);CHKERRQ(ierr); 382a8116848SStefano Zampini } else { 383a8116848SStefano Zampini ierr = MatISGetLocalMat(*newmat,&newlocmat);CHKERRQ(ierr); 384a8116848SStefano Zampini } 385a8116848SStefano Zampini ierr = MatISGetLocalMat(mat,&locmat);CHKERRQ(ierr); 386a8116848SStefano Zampini newmatis = (Mat_IS*)(*newmat)->data; 387a8116848SStefano Zampini ierr = MatGetSubMatrix(locmat,newmatis->getsub_ris,newmatis->getsub_cis,scall,&newlocmat);CHKERRQ(ierr); 388a8116848SStefano Zampini if (scall == MAT_INITIAL_MATRIX) { 389a8116848SStefano Zampini ierr = MatISSetLocalMat(*newmat,newlocmat);CHKERRQ(ierr); 390a8116848SStefano Zampini ierr = MatDestroy(&newlocmat);CHKERRQ(ierr); 391a8116848SStefano Zampini } 392a8116848SStefano Zampini ierr = MatAssemblyBegin(*newmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 393a8116848SStefano Zampini ierr = MatAssemblyEnd(*newmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 394a8116848SStefano Zampini PetscFunctionReturn(0); 395a8116848SStefano Zampini } 396a8116848SStefano Zampini 397a8116848SStefano Zampini #undef __FUNCT__ 3982b404112SStefano Zampini #define __FUNCT__ "MatCopy_IS" 399a8116848SStefano Zampini static PetscErrorCode MatCopy_IS(Mat A,Mat B,MatStructure str) 4002b404112SStefano Zampini { 4012b404112SStefano Zampini Mat_IS *a = (Mat_IS*)A->data,*b; 4022b404112SStefano Zampini PetscBool ismatis; 4032b404112SStefano Zampini PetscErrorCode ierr; 4042b404112SStefano Zampini 4052b404112SStefano Zampini PetscFunctionBegin; 4062b404112SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)B,MATIS,&ismatis);CHKERRQ(ierr); 4072b404112SStefano Zampini if (!ismatis) SETERRQ(PetscObjectComm((PetscObject)B),PETSC_ERR_SUP,"Need to be implemented"); 4082b404112SStefano Zampini b = (Mat_IS*)B->data; 4092b404112SStefano Zampini ierr = MatCopy(a->A,b->A,str);CHKERRQ(ierr); 4102b404112SStefano Zampini PetscFunctionReturn(0); 4112b404112SStefano Zampini } 4122b404112SStefano Zampini 4132b404112SStefano Zampini #undef __FUNCT__ 4146bd84002SStefano Zampini #define __FUNCT__ "MatMissingDiagonal_IS" 415a8116848SStefano Zampini static PetscErrorCode MatMissingDiagonal_IS(Mat A,PetscBool *missing,PetscInt *d) 4166bd84002SStefano Zampini { 417527b2640SStefano Zampini Vec v; 418527b2640SStefano Zampini const PetscScalar *array; 419527b2640SStefano Zampini PetscInt i,n; 4206bd84002SStefano Zampini PetscErrorCode ierr; 4216bd84002SStefano Zampini 4226bd84002SStefano Zampini PetscFunctionBegin; 423527b2640SStefano Zampini *missing = PETSC_FALSE; 424527b2640SStefano Zampini ierr = MatCreateVecs(A,NULL,&v);CHKERRQ(ierr); 425527b2640SStefano Zampini ierr = MatGetDiagonal(A,v);CHKERRQ(ierr); 426527b2640SStefano Zampini ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr); 427527b2640SStefano Zampini ierr = VecGetArrayRead(v,&array);CHKERRQ(ierr); 428527b2640SStefano Zampini for (i=0;i<n;i++) if (array[i] == 0.) break; 429527b2640SStefano Zampini ierr = VecRestoreArrayRead(v,&array);CHKERRQ(ierr); 430527b2640SStefano Zampini ierr = VecDestroy(&v);CHKERRQ(ierr); 431527b2640SStefano Zampini if (i != n) *missing = PETSC_TRUE; 432527b2640SStefano Zampini if (d) { 433527b2640SStefano Zampini *d = -1; 434527b2640SStefano Zampini if (*missing) { 435527b2640SStefano Zampini PetscInt rstart; 436527b2640SStefano Zampini ierr = MatGetOwnershipRange(A,&rstart,NULL);CHKERRQ(ierr); 437527b2640SStefano Zampini *d = i+rstart; 438527b2640SStefano Zampini } 439527b2640SStefano Zampini } 4406bd84002SStefano Zampini PetscFunctionReturn(0); 4416bd84002SStefano Zampini } 4426bd84002SStefano Zampini 4436bd84002SStefano Zampini #undef __FUNCT__ 44428f4e0baSStefano Zampini #define __FUNCT__ "MatISComputeSF_Private" 445a72627d2SStefano Zampini static PetscErrorCode MatISComputeSF_Private(Mat B) 44628f4e0baSStefano Zampini { 44728f4e0baSStefano Zampini Mat_IS *matis = (Mat_IS*)(B->data); 44828f4e0baSStefano Zampini const PetscInt *gidxs; 44928f4e0baSStefano Zampini PetscErrorCode ierr; 45028f4e0baSStefano Zampini 45128f4e0baSStefano Zampini PetscFunctionBegin; 45228f4e0baSStefano Zampini ierr = MatGetSize(matis->A,&matis->sf_nleaves,NULL);CHKERRQ(ierr); 45328f4e0baSStefano Zampini ierr = MatGetLocalSize(B,&matis->sf_nroots,NULL);CHKERRQ(ierr); 45428f4e0baSStefano Zampini ierr = PetscSFCreate(PetscObjectComm((PetscObject)B),&matis->sf);CHKERRQ(ierr); 4553bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(B->rmap->mapping,&gidxs);CHKERRQ(ierr); 45628f4e0baSStefano Zampini ierr = PetscSFSetGraphLayout(matis->sf,B->rmap,matis->sf_nleaves,NULL,PETSC_OWN_POINTER,gidxs);CHKERRQ(ierr); 4573bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(B->rmap->mapping,&gidxs);CHKERRQ(ierr); 45828f4e0baSStefano Zampini ierr = PetscMalloc2(matis->sf_nroots,&matis->sf_rootdata,matis->sf_nleaves,&matis->sf_leafdata);CHKERRQ(ierr); 459a8116848SStefano Zampini if (B->rmap->mapping != B->cmap->mapping) { /* setup SF for columns */ 460a8116848SStefano Zampini ierr = MatGetSize(matis->A,NULL,&matis->csf_nleaves);CHKERRQ(ierr); 461a8116848SStefano Zampini ierr = MatGetLocalSize(B,NULL,&matis->csf_nroots);CHKERRQ(ierr); 462a8116848SStefano Zampini ierr = PetscSFCreate(PetscObjectComm((PetscObject)B),&matis->csf);CHKERRQ(ierr); 463a8116848SStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(B->cmap->mapping,&gidxs);CHKERRQ(ierr); 464a8116848SStefano Zampini ierr = PetscSFSetGraphLayout(matis->csf,B->cmap,matis->csf_nleaves,NULL,PETSC_OWN_POINTER,gidxs);CHKERRQ(ierr); 465a8116848SStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(B->cmap->mapping,&gidxs);CHKERRQ(ierr); 466a8116848SStefano Zampini ierr = PetscMalloc2(matis->csf_nroots,&matis->csf_rootdata,matis->csf_nleaves,&matis->csf_leafdata);CHKERRQ(ierr); 467a8116848SStefano Zampini } else { 468a8116848SStefano Zampini matis->csf = matis->sf; 469a8116848SStefano Zampini matis->csf_nleaves = matis->sf_nleaves; 470a8116848SStefano Zampini matis->csf_nroots = matis->sf_nroots; 471a8116848SStefano Zampini matis->csf_leafdata = matis->sf_leafdata; 472a8116848SStefano Zampini matis->csf_rootdata = matis->sf_rootdata; 473a8116848SStefano Zampini } 47428f4e0baSStefano Zampini PetscFunctionReturn(0); 47528f4e0baSStefano Zampini } 4762e1947a5SStefano Zampini 4772e1947a5SStefano Zampini #undef __FUNCT__ 4782e1947a5SStefano Zampini #define __FUNCT__ "MatISSetPreallocation" 479eb82efa4SStefano Zampini /*@ 480a88811baSStefano Zampini MatISSetPreallocation - Preallocates memory for a MATIS parallel matrix. 481a88811baSStefano Zampini 482a88811baSStefano Zampini Collective on MPI_Comm 483a88811baSStefano Zampini 484a88811baSStefano Zampini Input Parameters: 485a88811baSStefano Zampini + B - the matrix 486a88811baSStefano Zampini . d_nz - number of nonzeros per row in DIAGONAL portion of local submatrix 487a88811baSStefano Zampini (same value is used for all local rows) 488a88811baSStefano Zampini . d_nnz - array containing the number of nonzeros in the various rows of the 489a88811baSStefano Zampini DIAGONAL portion of the local submatrix (possibly different for each row) 490a88811baSStefano Zampini or NULL, if d_nz is used to specify the nonzero structure. 491a88811baSStefano Zampini The size of this array is equal to the number of local rows, i.e 'm'. 492a88811baSStefano Zampini For matrices that will be factored, you must leave room for (and set) 493a88811baSStefano Zampini the diagonal entry even if it is zero. 494a88811baSStefano Zampini . o_nz - number of nonzeros per row in the OFF-DIAGONAL portion of local 495a88811baSStefano Zampini submatrix (same value is used for all local rows). 496a88811baSStefano Zampini - o_nnz - array containing the number of nonzeros in the various rows of the 497a88811baSStefano Zampini OFF-DIAGONAL portion of the local submatrix (possibly different for 498a88811baSStefano Zampini each row) or NULL, if o_nz is used to specify the nonzero 499a88811baSStefano Zampini structure. The size of this array is equal to the number 500a88811baSStefano Zampini of local rows, i.e 'm'. 501a88811baSStefano Zampini 502a88811baSStefano Zampini If the *_nnz parameter is given then the *_nz parameter is ignored 503a88811baSStefano Zampini 504a88811baSStefano Zampini Level: intermediate 505a88811baSStefano Zampini 506a88811baSStefano Zampini Notes: This function has the same interface as the MPIAIJ preallocation routine in order to simplify the transition 507a88811baSStefano Zampini from the asssembled format to the unassembled one. It overestimates the preallocation of MATIS local 508a88811baSStefano Zampini matrices; for exact preallocation, the user should set the preallocation directly on local matrix objects. 509a88811baSStefano Zampini 510a88811baSStefano Zampini .keywords: matrix 511a88811baSStefano Zampini 5123c212e90SHong Zhang .seealso: MatCreate(), MatCreateIS(), MatMPIAIJSetPreallocation(), MatISGetLocalMat(), MATIS 513a88811baSStefano Zampini @*/ 5142e1947a5SStefano Zampini PetscErrorCode MatISSetPreallocation(Mat B,PetscInt d_nz,const PetscInt d_nnz[],PetscInt o_nz,const PetscInt o_nnz[]) 5152e1947a5SStefano Zampini { 5162e1947a5SStefano Zampini PetscErrorCode ierr; 5172e1947a5SStefano Zampini 5182e1947a5SStefano Zampini PetscFunctionBegin; 5192e1947a5SStefano Zampini PetscValidHeaderSpecific(B,MAT_CLASSID,1); 5202e1947a5SStefano Zampini PetscValidType(B,1); 5212e1947a5SStefano Zampini ierr = PetscTryMethod(B,"MatISSetPreallocation_C",(Mat,PetscInt,const PetscInt[],PetscInt,const PetscInt[]),(B,d_nz,d_nnz,o_nz,o_nnz));CHKERRQ(ierr); 5222e1947a5SStefano Zampini PetscFunctionReturn(0); 5232e1947a5SStefano Zampini } 5242e1947a5SStefano Zampini 5252e1947a5SStefano Zampini #undef __FUNCT__ 5262e1947a5SStefano Zampini #define __FUNCT__ "MatISSetPreallocation_IS" 5277230de76SStefano Zampini static PetscErrorCode MatISSetPreallocation_IS(Mat B,PetscInt d_nz,const PetscInt d_nnz[],PetscInt o_nz,const PetscInt o_nnz[]) 5282e1947a5SStefano Zampini { 5292e1947a5SStefano Zampini Mat_IS *matis = (Mat_IS*)(B->data); 53028f4e0baSStefano Zampini PetscInt bs,i,nlocalcols; 5312e1947a5SStefano Zampini PetscErrorCode ierr; 5322e1947a5SStefano Zampini 5332e1947a5SStefano Zampini PetscFunctionBegin; 5346c4ed002SBarry Smith if (!matis->A) SETERRQ(PetscObjectComm((PetscObject)B),PETSC_ERR_SUP,"You should first call MatSetLocalToGlobalMapping"); 53528f4e0baSStefano Zampini if (!matis->sf) { /* setup SF if not yet created and allocate rootdata and leafdata */ 53628f4e0baSStefano Zampini ierr = MatISComputeSF_Private(B);CHKERRQ(ierr); 53728f4e0baSStefano Zampini } 5382e1947a5SStefano Zampini if (!d_nnz) { 53928f4e0baSStefano Zampini for (i=0;i<matis->sf_nroots;i++) matis->sf_rootdata[i] = d_nz; 5402e1947a5SStefano Zampini } else { 54128f4e0baSStefano Zampini for (i=0;i<matis->sf_nroots;i++) matis->sf_rootdata[i] = d_nnz[i]; 5422e1947a5SStefano Zampini } 5432e1947a5SStefano Zampini if (!o_nnz) { 54428f4e0baSStefano Zampini for (i=0;i<matis->sf_nroots;i++) matis->sf_rootdata[i] += o_nz; 5452e1947a5SStefano Zampini } else { 54628f4e0baSStefano Zampini for (i=0;i<matis->sf_nroots;i++) matis->sf_rootdata[i] += o_nnz[i]; 5472e1947a5SStefano Zampini } 54828f4e0baSStefano Zampini ierr = PetscSFBcastBegin(matis->sf,MPIU_INT,matis->sf_rootdata,matis->sf_leafdata);CHKERRQ(ierr); 54928f4e0baSStefano Zampini ierr = MatGetSize(matis->A,NULL,&nlocalcols);CHKERRQ(ierr); 55028f4e0baSStefano Zampini ierr = MatGetBlockSize(matis->A,&bs);CHKERRQ(ierr); 55128f4e0baSStefano Zampini ierr = PetscSFBcastEnd(matis->sf,MPIU_INT,matis->sf_rootdata,matis->sf_leafdata);CHKERRQ(ierr); 55228f4e0baSStefano Zampini for (i=0;i<matis->sf_nleaves;i++) { 55328f4e0baSStefano Zampini matis->sf_leafdata[i] = PetscMin(matis->sf_leafdata[i],nlocalcols); 5542e1947a5SStefano Zampini } 55528f4e0baSStefano Zampini ierr = MatSeqAIJSetPreallocation(matis->A,0,matis->sf_leafdata);CHKERRQ(ierr); 55628f4e0baSStefano Zampini for (i=0;i<matis->sf_nleaves/bs;i++) { 55728f4e0baSStefano Zampini matis->sf_leafdata[i] = matis->sf_leafdata[i*bs]/bs; 5582e1947a5SStefano Zampini } 55928f4e0baSStefano Zampini ierr = MatSeqBAIJSetPreallocation(matis->A,bs,0,matis->sf_leafdata);CHKERRQ(ierr); 56028f4e0baSStefano Zampini for (i=0;i<matis->sf_nleaves/bs;i++) { 56128f4e0baSStefano Zampini matis->sf_leafdata[i] = matis->sf_leafdata[i]-i; 5622e1947a5SStefano Zampini } 56328f4e0baSStefano Zampini ierr = MatSeqSBAIJSetPreallocation(matis->A,bs,0,matis->sf_leafdata);CHKERRQ(ierr); 5642e1947a5SStefano Zampini PetscFunctionReturn(0); 5652e1947a5SStefano Zampini } 566b4319ba4SBarry Smith 567b4319ba4SBarry Smith #undef __FUNCT__ 5683927de2eSStefano Zampini #define __FUNCT__ "MatISSetMPIXAIJPreallocation_Private" 5693927de2eSStefano Zampini PETSC_EXTERN PetscErrorCode MatISSetMPIXAIJPreallocation_Private(Mat A, Mat B, PetscBool maxreduce) 5703927de2eSStefano Zampini { 5713927de2eSStefano Zampini Mat_IS *matis = (Mat_IS*)(A->data); 5723927de2eSStefano Zampini PetscInt *my_dnz,*my_onz,*dnz,*onz,*mat_ranges,*row_ownership; 573ecf5a873SStefano Zampini const PetscInt *global_indices_r,*global_indices_c; 5743927de2eSStefano Zampini PetscInt i,j,bs,rows,cols; 5753927de2eSStefano Zampini PetscInt lrows,lcols; 5763927de2eSStefano Zampini PetscInt local_rows,local_cols; 5773927de2eSStefano Zampini PetscMPIInt nsubdomains; 5783927de2eSStefano Zampini PetscBool isdense,issbaij; 5793927de2eSStefano Zampini PetscErrorCode ierr; 5803927de2eSStefano Zampini 5813927de2eSStefano Zampini PetscFunctionBegin; 5823927de2eSStefano Zampini ierr = MPI_Comm_size(PetscObjectComm((PetscObject)A),&nsubdomains);CHKERRQ(ierr); 5833927de2eSStefano Zampini ierr = MatGetSize(A,&rows,&cols);CHKERRQ(ierr); 5843927de2eSStefano Zampini ierr = MatGetBlockSize(A,&bs);CHKERRQ(ierr); 5853927de2eSStefano Zampini ierr = MatGetSize(matis->A,&local_rows,&local_cols);CHKERRQ(ierr); 5863927de2eSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)matis->A,MATSEQDENSE,&isdense);CHKERRQ(ierr); 5873927de2eSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)matis->A,MATSEQSBAIJ,&issbaij);CHKERRQ(ierr); 588ecf5a873SStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(A->rmap->mapping,&global_indices_r);CHKERRQ(ierr); 589ecf5a873SStefano Zampini if (A->rmap->mapping != A->cmap->mapping) { 5907230de76SStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(A->cmap->mapping,&global_indices_c);CHKERRQ(ierr); 591ecf5a873SStefano Zampini } else { 592ecf5a873SStefano Zampini global_indices_c = global_indices_r; 593ecf5a873SStefano Zampini } 594ecf5a873SStefano Zampini 5953927de2eSStefano Zampini if (issbaij) { 5963927de2eSStefano Zampini ierr = MatGetRowUpperTriangular(matis->A);CHKERRQ(ierr); 5973927de2eSStefano Zampini } 5983927de2eSStefano Zampini /* 599ecf5a873SStefano Zampini An SF reduce is needed to sum up properly on shared rows. 6003927de2eSStefano Zampini Note that generally preallocation is not exact, since it overestimates nonzeros 6013927de2eSStefano Zampini */ 6023927de2eSStefano Zampini if (!matis->sf) { /* setup SF if not yet created and allocate rootdata and leafdata */ 6033927de2eSStefano Zampini ierr = MatISComputeSF_Private(A);CHKERRQ(ierr); 6043927de2eSStefano Zampini } 6053927de2eSStefano Zampini ierr = MatGetLocalSize(A,&lrows,&lcols);CHKERRQ(ierr); 6063927de2eSStefano Zampini ierr = MatPreallocateInitialize(PetscObjectComm((PetscObject)A),lrows,lcols,dnz,onz);CHKERRQ(ierr); 6073927de2eSStefano Zampini /* All processes need to compute entire row ownership */ 6083927de2eSStefano Zampini ierr = PetscMalloc1(rows,&row_ownership);CHKERRQ(ierr); 6093927de2eSStefano Zampini ierr = MatGetOwnershipRanges(A,(const PetscInt**)&mat_ranges);CHKERRQ(ierr); 6103927de2eSStefano Zampini for (i=0;i<nsubdomains;i++) { 6113927de2eSStefano Zampini for (j=mat_ranges[i];j<mat_ranges[i+1];j++) { 6123927de2eSStefano Zampini row_ownership[j] = i; 6133927de2eSStefano Zampini } 6143927de2eSStefano Zampini } 6157230de76SStefano Zampini ierr = MatGetOwnershipRangesColumn(A,(const PetscInt**)&mat_ranges);CHKERRQ(ierr); 6163927de2eSStefano Zampini 6173927de2eSStefano Zampini /* 6183927de2eSStefano Zampini my_dnz and my_onz contains exact contribution to preallocation from each local mat 6193927de2eSStefano Zampini then, they will be summed up properly. This way, preallocation is always sufficient 6203927de2eSStefano Zampini */ 6213927de2eSStefano Zampini ierr = PetscCalloc2(local_rows,&my_dnz,local_rows,&my_onz);CHKERRQ(ierr); 6223927de2eSStefano Zampini /* preallocation as a MATAIJ */ 6233927de2eSStefano Zampini if (isdense) { /* special case for dense local matrices */ 6243927de2eSStefano Zampini for (i=0;i<local_rows;i++) { 625ecf5a873SStefano Zampini PetscInt index_row = global_indices_r[i]; 6263927de2eSStefano Zampini for (j=i;j<local_rows;j++) { 6273927de2eSStefano Zampini PetscInt owner = row_ownership[index_row]; 628ecf5a873SStefano Zampini PetscInt index_col = global_indices_c[j]; 6293927de2eSStefano Zampini if (index_col > mat_ranges[owner]-1 && index_col < mat_ranges[owner+1] ) { /* diag block */ 6303927de2eSStefano Zampini my_dnz[i] += 1; 6313927de2eSStefano Zampini } else { /* offdiag block */ 6323927de2eSStefano Zampini my_onz[i] += 1; 6333927de2eSStefano Zampini } 6343927de2eSStefano Zampini /* same as before, interchanging rows and cols */ 6353927de2eSStefano Zampini if (i != j) { 6363927de2eSStefano Zampini owner = row_ownership[index_col]; 6373927de2eSStefano Zampini if (index_row > mat_ranges[owner]-1 && index_row < mat_ranges[owner+1] ) { 6383927de2eSStefano Zampini my_dnz[j] += 1; 6393927de2eSStefano Zampini } else { 6403927de2eSStefano Zampini my_onz[j] += 1; 6413927de2eSStefano Zampini } 6423927de2eSStefano Zampini } 6433927de2eSStefano Zampini } 6443927de2eSStefano Zampini } 645bb1015c3SStefano Zampini } else if (matis->A->ops->getrowij) { 646bb1015c3SStefano Zampini const PetscInt *ii,*jj,*jptr; 647bb1015c3SStefano Zampini PetscBool done; 648bb1015c3SStefano Zampini ierr = MatGetRowIJ(matis->A,0,PETSC_FALSE,PETSC_FALSE,&local_rows,&ii,&jj,&done);CHKERRQ(ierr); 649bb1015c3SStefano Zampini if (!done) SETERRQ1(PetscObjectComm((PetscObject)(matis->A)),PETSC_ERR_PLIB,"Error in MatGetRowIJ called from %s\n",__FUNCT__); 650bb1015c3SStefano Zampini jptr = jj; 651bb1015c3SStefano Zampini for (i=0;i<local_rows;i++) { 652bb1015c3SStefano Zampini PetscInt index_row = global_indices_r[i]; 653bb1015c3SStefano Zampini for (j=0;j<ii[i+1]-ii[i];j++,jptr++) { 654bb1015c3SStefano Zampini PetscInt owner = row_ownership[index_row]; 655bb1015c3SStefano Zampini PetscInt index_col = global_indices_c[*jptr]; 656bb1015c3SStefano Zampini if (index_col > mat_ranges[owner]-1 && index_col < mat_ranges[owner+1] ) { /* diag block */ 657bb1015c3SStefano Zampini my_dnz[i] += 1; 658bb1015c3SStefano Zampini } else { /* offdiag block */ 659bb1015c3SStefano Zampini my_onz[i] += 1; 660bb1015c3SStefano Zampini } 661bb1015c3SStefano Zampini /* same as before, interchanging rows and cols */ 662bb1015c3SStefano Zampini if (issbaij && index_col != index_row) { 663bb1015c3SStefano Zampini owner = row_ownership[index_col]; 664bb1015c3SStefano Zampini if (index_row > mat_ranges[owner]-1 && index_row < mat_ranges[owner+1] ) { 665bb1015c3SStefano Zampini my_dnz[*jptr] += 1; 666bb1015c3SStefano Zampini } else { 667bb1015c3SStefano Zampini my_onz[*jptr] += 1; 668bb1015c3SStefano Zampini } 669bb1015c3SStefano Zampini } 670bb1015c3SStefano Zampini } 671bb1015c3SStefano Zampini } 672bb1015c3SStefano Zampini ierr = MatRestoreRowIJ(matis->A,0,PETSC_FALSE,PETSC_FALSE,&local_rows,&ii,&jj,&done);CHKERRQ(ierr); 673bb1015c3SStefano Zampini if (!done) SETERRQ1(PetscObjectComm((PetscObject)(matis->A)),PETSC_ERR_PLIB,"Error in MatRestoreRowIJ called from %s\n",__FUNCT__); 674bb1015c3SStefano Zampini } else { /* loop over rows and use MatGetRow */ 6753927de2eSStefano Zampini for (i=0;i<local_rows;i++) { 6763927de2eSStefano Zampini const PetscInt *cols; 677ecf5a873SStefano Zampini PetscInt ncols,index_row = global_indices_r[i]; 6783927de2eSStefano Zampini ierr = MatGetRow(matis->A,i,&ncols,&cols,NULL);CHKERRQ(ierr); 6793927de2eSStefano Zampini for (j=0;j<ncols;j++) { 6803927de2eSStefano Zampini PetscInt owner = row_ownership[index_row]; 681ecf5a873SStefano Zampini PetscInt index_col = global_indices_c[cols[j]]; 6823927de2eSStefano Zampini if (index_col > mat_ranges[owner]-1 && index_col < mat_ranges[owner+1] ) { /* diag block */ 6833927de2eSStefano Zampini my_dnz[i] += 1; 6843927de2eSStefano Zampini } else { /* offdiag block */ 6853927de2eSStefano Zampini my_onz[i] += 1; 6863927de2eSStefano Zampini } 6873927de2eSStefano Zampini /* same as before, interchanging rows and cols */ 688d9a9e74cSStefano Zampini if (issbaij && index_col != index_row) { 6893927de2eSStefano Zampini owner = row_ownership[index_col]; 6903927de2eSStefano Zampini if (index_row > mat_ranges[owner]-1 && index_row < mat_ranges[owner+1] ) { 691d9a9e74cSStefano Zampini my_dnz[cols[j]] += 1; 6923927de2eSStefano Zampini } else { 693d9a9e74cSStefano Zampini my_onz[cols[j]] += 1; 6943927de2eSStefano Zampini } 6953927de2eSStefano Zampini } 6963927de2eSStefano Zampini } 6973927de2eSStefano Zampini ierr = MatRestoreRow(matis->A,i,&ncols,&cols,NULL);CHKERRQ(ierr); 6983927de2eSStefano Zampini } 6993927de2eSStefano Zampini } 700ecf5a873SStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(A->rmap->mapping,&global_indices_r);CHKERRQ(ierr); 701ecf5a873SStefano Zampini if (global_indices_c != global_indices_r) { 7027230de76SStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(A->cmap->mapping,&global_indices_c);CHKERRQ(ierr); 703ecf5a873SStefano Zampini } 7043927de2eSStefano Zampini ierr = PetscFree(row_ownership);CHKERRQ(ierr); 705ecf5a873SStefano Zampini 706ecf5a873SStefano Zampini /* Reduce my_dnz and my_onz */ 7073927de2eSStefano Zampini if (maxreduce) { 7083927de2eSStefano Zampini ierr = PetscSFReduceBegin(matis->sf,MPIU_INT,my_dnz,dnz,MPI_MAX);CHKERRQ(ierr); 7093927de2eSStefano Zampini ierr = PetscSFReduceBegin(matis->sf,MPIU_INT,my_onz,onz,MPI_MAX);CHKERRQ(ierr); 710bb1015c3SStefano Zampini ierr = PetscSFReduceEnd(matis->sf,MPIU_INT,my_dnz,dnz,MPI_MAX);CHKERRQ(ierr); 7113927de2eSStefano Zampini ierr = PetscSFReduceEnd(matis->sf,MPIU_INT,my_onz,onz,MPI_MAX);CHKERRQ(ierr); 7123927de2eSStefano Zampini } else { 7133927de2eSStefano Zampini ierr = PetscSFReduceBegin(matis->sf,MPIU_INT,my_dnz,dnz,MPI_SUM);CHKERRQ(ierr); 7143927de2eSStefano Zampini ierr = PetscSFReduceBegin(matis->sf,MPIU_INT,my_onz,onz,MPI_SUM);CHKERRQ(ierr); 715bb1015c3SStefano Zampini ierr = PetscSFReduceEnd(matis->sf,MPIU_INT,my_dnz,dnz,MPI_SUM);CHKERRQ(ierr); 7163927de2eSStefano Zampini ierr = PetscSFReduceEnd(matis->sf,MPIU_INT,my_onz,onz,MPI_SUM);CHKERRQ(ierr); 7173927de2eSStefano Zampini } 7183927de2eSStefano Zampini ierr = PetscFree2(my_dnz,my_onz);CHKERRQ(ierr); 7193927de2eSStefano Zampini 7203927de2eSStefano Zampini /* Resize preallocation if overestimated */ 7213927de2eSStefano Zampini for (i=0;i<lrows;i++) { 7223927de2eSStefano Zampini dnz[i] = PetscMin(dnz[i],lcols); 7233927de2eSStefano Zampini onz[i] = PetscMin(onz[i],cols-lcols); 7243927de2eSStefano Zampini } 7253927de2eSStefano Zampini /* set preallocation */ 7263927de2eSStefano Zampini ierr = MatMPIAIJSetPreallocation(B,0,dnz,0,onz);CHKERRQ(ierr); 7273927de2eSStefano Zampini for (i=0;i<lrows/bs;i++) { 7283927de2eSStefano Zampini dnz[i] = dnz[i*bs]/bs; 7293927de2eSStefano Zampini onz[i] = onz[i*bs]/bs; 7303927de2eSStefano Zampini } 7313927de2eSStefano Zampini ierr = MatMPIBAIJSetPreallocation(B,bs,0,dnz,0,onz);CHKERRQ(ierr); 7323927de2eSStefano Zampini ierr = MatMPISBAIJSetPreallocation(B,bs,0,dnz,0,onz);CHKERRQ(ierr); 7333927de2eSStefano Zampini ierr = MatPreallocateFinalize(dnz,onz);CHKERRQ(ierr); 7343927de2eSStefano Zampini if (issbaij) { 7353927de2eSStefano Zampini ierr = MatRestoreRowUpperTriangular(matis->A);CHKERRQ(ierr); 7363927de2eSStefano Zampini } 7373927de2eSStefano Zampini PetscFunctionReturn(0); 7383927de2eSStefano Zampini } 7393927de2eSStefano Zampini 7403927de2eSStefano Zampini #undef __FUNCT__ 741b7ce53b6SStefano Zampini #define __FUNCT__ "MatISGetMPIXAIJ_IS" 7427230de76SStefano Zampini static PetscErrorCode MatISGetMPIXAIJ_IS(Mat mat, MatReuse reuse, Mat *M) 743b7ce53b6SStefano Zampini { 744b7ce53b6SStefano Zampini Mat_IS *matis = (Mat_IS*)(mat->data); 745d9a9e74cSStefano Zampini Mat local_mat; 746b7ce53b6SStefano Zampini /* info on mat */ 7473cfa4ea4SStefano Zampini PetscInt bs,rows,cols,lrows,lcols; 748b7ce53b6SStefano Zampini PetscInt local_rows,local_cols; 749686e3a49SStefano Zampini PetscBool isdense,issbaij,isseqaij; 7507c03b4e8SStefano Zampini PetscMPIInt nsubdomains; 751b7ce53b6SStefano Zampini /* values insertion */ 752b7ce53b6SStefano Zampini PetscScalar *array; 753b7ce53b6SStefano Zampini /* work */ 754b7ce53b6SStefano Zampini PetscErrorCode ierr; 755b7ce53b6SStefano Zampini 756b7ce53b6SStefano Zampini PetscFunctionBegin; 757b7ce53b6SStefano Zampini /* get info from mat */ 7587c03b4e8SStefano Zampini ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&nsubdomains);CHKERRQ(ierr); 7597c03b4e8SStefano Zampini if (nsubdomains == 1) { 7607c03b4e8SStefano Zampini if (reuse == MAT_INITIAL_MATRIX) { 7617c03b4e8SStefano Zampini ierr = MatDuplicate(matis->A,MAT_COPY_VALUES,&(*M));CHKERRQ(ierr); 7627c03b4e8SStefano Zampini } else { 7637c03b4e8SStefano Zampini ierr = MatCopy(matis->A,*M,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 7647c03b4e8SStefano Zampini } 7657c03b4e8SStefano Zampini PetscFunctionReturn(0); 7667c03b4e8SStefano Zampini } 767b7ce53b6SStefano Zampini ierr = MatGetSize(mat,&rows,&cols);CHKERRQ(ierr); 768b7ce53b6SStefano Zampini ierr = MatGetBlockSize(mat,&bs);CHKERRQ(ierr); 7693cfa4ea4SStefano Zampini ierr = MatGetLocalSize(mat,&lrows,&lcols);CHKERRQ(ierr); 770b7ce53b6SStefano Zampini ierr = MatGetSize(matis->A,&local_rows,&local_cols);CHKERRQ(ierr); 771b7ce53b6SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)matis->A,MATSEQDENSE,&isdense);CHKERRQ(ierr); 772686e3a49SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)matis->A,MATSEQAIJ,&isseqaij);CHKERRQ(ierr); 773b7ce53b6SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)matis->A,MATSEQSBAIJ,&issbaij);CHKERRQ(ierr); 774b7ce53b6SStefano Zampini 775b7ce53b6SStefano Zampini if (reuse == MAT_INITIAL_MATRIX) { 776b7ce53b6SStefano Zampini MatType new_mat_type; 7773927de2eSStefano Zampini PetscBool issbaij_red; 778b7ce53b6SStefano Zampini 779b7ce53b6SStefano Zampini /* determining new matrix type */ 780b2566f29SBarry Smith ierr = MPIU_Allreduce(&issbaij,&issbaij_red,1,MPIU_BOOL,MPI_LAND,PetscObjectComm((PetscObject)mat));CHKERRQ(ierr); 781b7ce53b6SStefano Zampini if (issbaij_red) { 782b7ce53b6SStefano Zampini new_mat_type = MATSBAIJ; 783b7ce53b6SStefano Zampini } else { 784b7ce53b6SStefano Zampini if (bs>1) { 785b7ce53b6SStefano Zampini new_mat_type = MATBAIJ; 786b7ce53b6SStefano Zampini } else { 787b7ce53b6SStefano Zampini new_mat_type = MATAIJ; 788b7ce53b6SStefano Zampini } 789b7ce53b6SStefano Zampini } 790b7ce53b6SStefano Zampini 7913927de2eSStefano Zampini ierr = MatCreate(PetscObjectComm((PetscObject)mat),M);CHKERRQ(ierr); 7923cfa4ea4SStefano Zampini ierr = MatSetSizes(*M,lrows,lcols,rows,cols);CHKERRQ(ierr); 7933927de2eSStefano Zampini ierr = MatSetBlockSize(*M,bs);CHKERRQ(ierr); 7943927de2eSStefano Zampini ierr = MatSetType(*M,new_mat_type);CHKERRQ(ierr); 7953927de2eSStefano Zampini ierr = MatISSetMPIXAIJPreallocation_Private(mat,*M,PETSC_FALSE);CHKERRQ(ierr); 796b7ce53b6SStefano Zampini } else { 7973cfa4ea4SStefano Zampini PetscInt mbs,mrows,mcols,mlrows,mlcols; 798b7ce53b6SStefano Zampini /* some checks */ 799b7ce53b6SStefano Zampini ierr = MatGetBlockSize(*M,&mbs);CHKERRQ(ierr); 800b7ce53b6SStefano Zampini ierr = MatGetSize(*M,&mrows,&mcols);CHKERRQ(ierr); 8013cfa4ea4SStefano Zampini ierr = MatGetLocalSize(*M,&mlrows,&mlcols);CHKERRQ(ierr); 8026c4ed002SBarry Smith if (mrows != rows) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot reuse matrix. Wrong number of rows (%d != %d)",rows,mrows); 8036c4ed002SBarry Smith if (mcols != cols) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot reuse matrix. Wrong number of cols (%d != %d)",cols,mcols); 8046c4ed002SBarry Smith if (mlrows != lrows) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot reuse matrix. Wrong number of local rows (%d != %d)",lrows,mlrows); 8056c4ed002SBarry Smith if (mlcols != lcols) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot reuse matrix. Wrong number of local cols (%d != %d)",lcols,mlcols); 8066c4ed002SBarry Smith if (mbs != bs) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot reuse matrix. Wrong block size (%d != %d)",bs,mbs); 807b7ce53b6SStefano Zampini ierr = MatZeroEntries(*M);CHKERRQ(ierr); 808b7ce53b6SStefano Zampini } 809d9a9e74cSStefano Zampini 810d9a9e74cSStefano Zampini if (issbaij) { 811d9a9e74cSStefano Zampini ierr = MatConvert(matis->A,MATSEQBAIJ,MAT_INITIAL_MATRIX,&local_mat);CHKERRQ(ierr); 812d9a9e74cSStefano Zampini } else { 813d9a9e74cSStefano Zampini ierr = PetscObjectReference((PetscObject)matis->A);CHKERRQ(ierr); 814d9a9e74cSStefano Zampini local_mat = matis->A; 815d9a9e74cSStefano Zampini } 816686e3a49SStefano Zampini 817b7ce53b6SStefano Zampini /* Set values */ 818ecf5a873SStefano Zampini ierr = MatSetLocalToGlobalMapping(*M,mat->rmap->mapping,mat->cmap->mapping);CHKERRQ(ierr); 819b7ce53b6SStefano Zampini if (isdense) { /* special case for dense local matrices */ 820ecf5a873SStefano Zampini PetscInt i,*dummy_rows,*dummy_cols; 821ecf5a873SStefano Zampini 822ecf5a873SStefano Zampini if (local_rows != local_cols) { 823ecf5a873SStefano Zampini ierr = PetscMalloc2(local_rows,&dummy_rows,local_cols,&dummy_cols);CHKERRQ(ierr); 824ecf5a873SStefano Zampini for (i=0;i<local_rows;i++) dummy_rows[i] = i; 825ecf5a873SStefano Zampini for (i=0;i<local_cols;i++) dummy_cols[i] = i; 826ecf5a873SStefano Zampini } else { 827ecf5a873SStefano Zampini ierr = PetscMalloc1(local_rows,&dummy_rows);CHKERRQ(ierr); 828ecf5a873SStefano Zampini for (i=0;i<local_rows;i++) dummy_rows[i] = i; 829ecf5a873SStefano Zampini dummy_cols = dummy_rows; 830ecf5a873SStefano Zampini } 831b7ce53b6SStefano Zampini ierr = MatSetOption(*M,MAT_ROW_ORIENTED,PETSC_FALSE);CHKERRQ(ierr); 832d9a9e74cSStefano Zampini ierr = MatDenseGetArray(local_mat,&array);CHKERRQ(ierr); 833ecf5a873SStefano Zampini ierr = MatSetValuesLocal(*M,local_rows,dummy_rows,local_cols,dummy_cols,array,ADD_VALUES);CHKERRQ(ierr); 834d9a9e74cSStefano Zampini ierr = MatDenseRestoreArray(local_mat,&array);CHKERRQ(ierr); 835ecf5a873SStefano Zampini if (dummy_rows != dummy_cols) { 836ecf5a873SStefano Zampini ierr = PetscFree2(dummy_rows,dummy_cols);CHKERRQ(ierr); 837ecf5a873SStefano Zampini } else { 838ecf5a873SStefano Zampini ierr = PetscFree(dummy_rows);CHKERRQ(ierr); 839ecf5a873SStefano Zampini } 840686e3a49SStefano Zampini } else if (isseqaij) { 841ecf5a873SStefano Zampini PetscInt i,nvtxs,*xadj,*adjncy; 842686e3a49SStefano Zampini PetscBool done; 843686e3a49SStefano Zampini 844d9a9e74cSStefano Zampini ierr = MatGetRowIJ(local_mat,0,PETSC_FALSE,PETSC_FALSE,&nvtxs,(const PetscInt**)&xadj,(const PetscInt**)&adjncy,&done);CHKERRQ(ierr); 845bb1015c3SStefano Zampini if (!done) SETERRQ1(PetscObjectComm((PetscObject)local_mat),PETSC_ERR_PLIB,"Error in MatGetRowIJ called from %s\n",__FUNCT__); 846d9a9e74cSStefano Zampini ierr = MatSeqAIJGetArray(local_mat,&array);CHKERRQ(ierr); 847686e3a49SStefano Zampini for (i=0;i<nvtxs;i++) { 848ecf5a873SStefano Zampini ierr = MatSetValuesLocal(*M,1,&i,xadj[i+1]-xadj[i],adjncy+xadj[i],array+xadj[i],ADD_VALUES);CHKERRQ(ierr); 849686e3a49SStefano Zampini } 850d9a9e74cSStefano Zampini ierr = MatRestoreRowIJ(local_mat,0,PETSC_FALSE,PETSC_FALSE,&nvtxs,(const PetscInt**)&xadj,(const PetscInt**)&adjncy,&done);CHKERRQ(ierr); 851bb1015c3SStefano Zampini if (!done) SETERRQ1(PetscObjectComm((PetscObject)local_mat),PETSC_ERR_PLIB,"Error in MatRestoreRowIJ called from %s\n",__FUNCT__); 852d9a9e74cSStefano Zampini ierr = MatSeqAIJRestoreArray(local_mat,&array);CHKERRQ(ierr); 853686e3a49SStefano Zampini } else { /* very basic values insertion for all other matrix types */ 854ecf5a873SStefano Zampini PetscInt i; 855c0962df8SStefano Zampini 856686e3a49SStefano Zampini for (i=0;i<local_rows;i++) { 857686e3a49SStefano Zampini PetscInt j; 858ecf5a873SStefano Zampini const PetscInt *local_indices_cols; 859686e3a49SStefano Zampini 860ecf5a873SStefano Zampini ierr = MatGetRow(local_mat,i,&j,&local_indices_cols,(const PetscScalar**)&array);CHKERRQ(ierr); 861ecf5a873SStefano Zampini ierr = MatSetValuesLocal(*M,1,&i,j,local_indices_cols,array,ADD_VALUES);CHKERRQ(ierr); 862ecf5a873SStefano Zampini ierr = MatRestoreRow(local_mat,i,&j,&local_indices_cols,(const PetscScalar**)&array);CHKERRQ(ierr); 863686e3a49SStefano Zampini } 864b7ce53b6SStefano Zampini } 865b7ce53b6SStefano Zampini ierr = MatAssemblyBegin(*M,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 866d9a9e74cSStefano Zampini ierr = MatDestroy(&local_mat);CHKERRQ(ierr); 867b7ce53b6SStefano Zampini ierr = MatAssemblyEnd(*M,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 868b7ce53b6SStefano Zampini if (isdense) { 869b7ce53b6SStefano Zampini ierr = MatSetOption(*M,MAT_ROW_ORIENTED,PETSC_TRUE);CHKERRQ(ierr); 870b7ce53b6SStefano Zampini } 871b7ce53b6SStefano Zampini PetscFunctionReturn(0); 872b7ce53b6SStefano Zampini } 873b7ce53b6SStefano Zampini 874b7ce53b6SStefano Zampini #undef __FUNCT__ 875b7ce53b6SStefano Zampini #define __FUNCT__ "MatISGetMPIXAIJ" 876b7ce53b6SStefano Zampini /*@ 877b7ce53b6SStefano Zampini MatISGetMPIXAIJ - Converts MATIS matrix into a parallel AIJ format 878b7ce53b6SStefano Zampini 879b7ce53b6SStefano Zampini Input Parameter: 880b7ce53b6SStefano Zampini . mat - the matrix (should be of type MATIS) 881b7ce53b6SStefano Zampini . reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 882b7ce53b6SStefano Zampini 883b7ce53b6SStefano Zampini Output Parameter: 884b7ce53b6SStefano Zampini . newmat - the matrix in AIJ format 885b7ce53b6SStefano Zampini 886b7ce53b6SStefano Zampini Level: developer 887b7ce53b6SStefano Zampini 888eb82efa4SStefano Zampini Notes: mat and *newmat cannot be the same object when MAT_REUSE_MATRIX is requested. 889b7ce53b6SStefano Zampini 890b7ce53b6SStefano Zampini .seealso: MATIS 891b7ce53b6SStefano Zampini @*/ 892b7ce53b6SStefano Zampini PetscErrorCode MatISGetMPIXAIJ(Mat mat, MatReuse reuse, Mat *newmat) 893b7ce53b6SStefano Zampini { 894b7ce53b6SStefano Zampini PetscErrorCode ierr; 895b7ce53b6SStefano Zampini 896b7ce53b6SStefano Zampini PetscFunctionBegin; 897b7ce53b6SStefano Zampini PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 898b7ce53b6SStefano Zampini PetscValidLogicalCollectiveEnum(mat,reuse,2); 899b7ce53b6SStefano Zampini PetscValidPointer(newmat,3); 900b7ce53b6SStefano Zampini if (reuse != MAT_INITIAL_MATRIX) { 901b7ce53b6SStefano Zampini PetscValidHeaderSpecific(*newmat,MAT_CLASSID,3); 902b7ce53b6SStefano Zampini PetscCheckSameComm(mat,1,*newmat,3); 9036c4ed002SBarry Smith if (mat == *newmat) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot reuse the same matrix"); 904b7ce53b6SStefano Zampini } 905b7ce53b6SStefano Zampini ierr = PetscUseMethod(mat,"MatISGetMPIXAIJ_C",(Mat,MatReuse,Mat*),(mat,reuse,newmat));CHKERRQ(ierr); 906b7ce53b6SStefano Zampini PetscFunctionReturn(0); 907b7ce53b6SStefano Zampini } 908b7ce53b6SStefano Zampini 909b7ce53b6SStefano Zampini #undef __FUNCT__ 910ad6194a2SStefano Zampini #define __FUNCT__ "MatDuplicate_IS" 911ad6194a2SStefano Zampini PetscErrorCode MatDuplicate_IS(Mat mat,MatDuplicateOption op,Mat *newmat) 912ad6194a2SStefano Zampini { 913ad6194a2SStefano Zampini PetscErrorCode ierr; 914ad6194a2SStefano Zampini Mat_IS *matis = (Mat_IS*)(mat->data); 915ad6194a2SStefano Zampini PetscInt bs,m,n,M,N; 916ad6194a2SStefano Zampini Mat B,localmat; 917ad6194a2SStefano Zampini 918ad6194a2SStefano Zampini PetscFunctionBegin; 919ad6194a2SStefano Zampini ierr = MatGetBlockSize(mat,&bs);CHKERRQ(ierr); 920ad6194a2SStefano Zampini ierr = MatGetSize(mat,&M,&N);CHKERRQ(ierr); 921ad6194a2SStefano Zampini ierr = MatGetLocalSize(mat,&m,&n);CHKERRQ(ierr); 922e176bc59SStefano Zampini ierr = MatCreateIS(PetscObjectComm((PetscObject)mat),bs,m,n,M,N,mat->rmap->mapping,mat->cmap->mapping,&B);CHKERRQ(ierr); 923ad6194a2SStefano Zampini ierr = MatDuplicate(matis->A,op,&localmat);CHKERRQ(ierr); 924ad6194a2SStefano Zampini ierr = MatISSetLocalMat(B,localmat);CHKERRQ(ierr); 925b3317aa8SStefano Zampini ierr = MatDestroy(&localmat);CHKERRQ(ierr); 926ad6194a2SStefano Zampini ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 927ad6194a2SStefano Zampini ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 928ad6194a2SStefano Zampini *newmat = B; 929ad6194a2SStefano Zampini PetscFunctionReturn(0); 930ad6194a2SStefano Zampini } 931ad6194a2SStefano Zampini 932ad6194a2SStefano Zampini #undef __FUNCT__ 93369796d55SStefano Zampini #define __FUNCT__ "MatIsHermitian_IS" 934a8116848SStefano Zampini static PetscErrorCode MatIsHermitian_IS(Mat A,PetscReal tol,PetscBool *flg) 93569796d55SStefano Zampini { 93669796d55SStefano Zampini PetscErrorCode ierr; 93769796d55SStefano Zampini Mat_IS *matis = (Mat_IS*)A->data; 93869796d55SStefano Zampini PetscBool local_sym; 93969796d55SStefano Zampini 94069796d55SStefano Zampini PetscFunctionBegin; 94169796d55SStefano Zampini ierr = MatIsHermitian(matis->A,tol,&local_sym);CHKERRQ(ierr); 942b2566f29SBarry Smith ierr = MPIU_Allreduce(&local_sym,flg,1,MPIU_BOOL,MPI_LAND,PetscObjectComm((PetscObject)A));CHKERRQ(ierr); 94369796d55SStefano Zampini PetscFunctionReturn(0); 94469796d55SStefano Zampini } 94569796d55SStefano Zampini 94669796d55SStefano Zampini #undef __FUNCT__ 94769796d55SStefano Zampini #define __FUNCT__ "MatIsSymmetric_IS" 948a8116848SStefano Zampini static PetscErrorCode MatIsSymmetric_IS(Mat A,PetscReal tol,PetscBool *flg) 94969796d55SStefano Zampini { 95069796d55SStefano Zampini PetscErrorCode ierr; 95169796d55SStefano Zampini Mat_IS *matis = (Mat_IS*)A->data; 95269796d55SStefano Zampini PetscBool local_sym; 95369796d55SStefano Zampini 95469796d55SStefano Zampini PetscFunctionBegin; 95569796d55SStefano Zampini ierr = MatIsSymmetric(matis->A,tol,&local_sym);CHKERRQ(ierr); 956b2566f29SBarry Smith ierr = MPIU_Allreduce(&local_sym,flg,1,MPIU_BOOL,MPI_LAND,PetscObjectComm((PetscObject)A));CHKERRQ(ierr); 95769796d55SStefano Zampini PetscFunctionReturn(0); 95869796d55SStefano Zampini } 95969796d55SStefano Zampini 96069796d55SStefano Zampini #undef __FUNCT__ 961b4319ba4SBarry Smith #define __FUNCT__ "MatDestroy_IS" 962a8116848SStefano Zampini static PetscErrorCode MatDestroy_IS(Mat A) 963b4319ba4SBarry Smith { 964dfbe8321SBarry Smith PetscErrorCode ierr; 965b4319ba4SBarry Smith Mat_IS *b = (Mat_IS*)A->data; 966b4319ba4SBarry Smith 967b4319ba4SBarry Smith PetscFunctionBegin; 9686bf464f9SBarry Smith ierr = MatDestroy(&b->A);CHKERRQ(ierr); 969e176bc59SStefano Zampini ierr = VecScatterDestroy(&b->cctx);CHKERRQ(ierr); 970e176bc59SStefano Zampini ierr = VecScatterDestroy(&b->rctx);CHKERRQ(ierr); 9716bf464f9SBarry Smith ierr = VecDestroy(&b->x);CHKERRQ(ierr); 9726bf464f9SBarry Smith ierr = VecDestroy(&b->y);CHKERRQ(ierr); 9733fd1c9e7SStefano Zampini ierr = VecDestroy(&b->counter);CHKERRQ(ierr); 974a8116848SStefano Zampini ierr = ISDestroy(&b->getsub_ris);CHKERRQ(ierr); 975a8116848SStefano Zampini ierr = ISDestroy(&b->getsub_cis);CHKERRQ(ierr); 976a8116848SStefano Zampini if (b->sf != b->csf) { 977a8116848SStefano Zampini ierr = PetscSFDestroy(&b->csf);CHKERRQ(ierr); 978a8116848SStefano Zampini ierr = PetscFree2(b->csf_rootdata,b->csf_leafdata);CHKERRQ(ierr); 979a8116848SStefano Zampini } 98028f4e0baSStefano Zampini ierr = PetscSFDestroy(&b->sf);CHKERRQ(ierr); 98128f4e0baSStefano Zampini ierr = PetscFree2(b->sf_rootdata,b->sf_leafdata);CHKERRQ(ierr); 982bf0cc555SLisandro Dalcin ierr = PetscFree(A->data);CHKERRQ(ierr); 983dbd8c25aSHong Zhang ierr = PetscObjectChangeTypeName((PetscObject)A,0);CHKERRQ(ierr); 984bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatISGetLocalMat_C",NULL);CHKERRQ(ierr); 985b7ce53b6SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatISSetLocalMat_C",NULL);CHKERRQ(ierr); 986b7ce53b6SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatISGetMPIXAIJ_C",NULL);CHKERRQ(ierr); 9872e1947a5SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatISSetPreallocation_C",NULL);CHKERRQ(ierr); 988b4319ba4SBarry Smith PetscFunctionReturn(0); 989b4319ba4SBarry Smith } 990b4319ba4SBarry Smith 991b4319ba4SBarry Smith #undef __FUNCT__ 992b4319ba4SBarry Smith #define __FUNCT__ "MatMult_IS" 993a8116848SStefano Zampini static PetscErrorCode MatMult_IS(Mat A,Vec x,Vec y) 994b4319ba4SBarry Smith { 995dfbe8321SBarry Smith PetscErrorCode ierr; 996b4319ba4SBarry Smith Mat_IS *is = (Mat_IS*)A->data; 997b4319ba4SBarry Smith PetscScalar zero = 0.0; 998b4319ba4SBarry Smith 999b4319ba4SBarry Smith PetscFunctionBegin; 1000b4319ba4SBarry Smith /* scatter the global vector x into the local work vector */ 1001e176bc59SStefano Zampini ierr = VecScatterBegin(is->cctx,x,is->x,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1002e176bc59SStefano Zampini ierr = VecScatterEnd(is->cctx,x,is->x,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1003b4319ba4SBarry Smith 1004b4319ba4SBarry Smith /* multiply the local matrix */ 1005b4319ba4SBarry Smith ierr = MatMult(is->A,is->x,is->y);CHKERRQ(ierr); 1006b4319ba4SBarry Smith 1007b4319ba4SBarry Smith /* scatter product back into global memory */ 10082dcb1b2aSMatthew Knepley ierr = VecSet(y,zero);CHKERRQ(ierr); 1009e176bc59SStefano Zampini ierr = VecScatterBegin(is->rctx,is->y,y,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 1010e176bc59SStefano Zampini ierr = VecScatterEnd(is->rctx,is->y,y,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 1011b4319ba4SBarry Smith PetscFunctionReturn(0); 1012b4319ba4SBarry Smith } 1013b4319ba4SBarry Smith 1014b4319ba4SBarry Smith #undef __FUNCT__ 10152e74eeadSLisandro Dalcin #define __FUNCT__ "MatMultAdd_IS" 1016a8116848SStefano Zampini static PetscErrorCode MatMultAdd_IS(Mat A,Vec v1,Vec v2,Vec v3) 10172e74eeadSLisandro Dalcin { 1018650997f4SStefano Zampini Vec temp_vec; 10192e74eeadSLisandro Dalcin PetscErrorCode ierr; 10202e74eeadSLisandro Dalcin 10212e74eeadSLisandro Dalcin PetscFunctionBegin; /* v3 = v2 + A * v1.*/ 1022650997f4SStefano Zampini if (v3 != v2) { 1023650997f4SStefano Zampini ierr = MatMult(A,v1,v3);CHKERRQ(ierr); 1024650997f4SStefano Zampini ierr = VecAXPY(v3,1.0,v2);CHKERRQ(ierr); 1025650997f4SStefano Zampini } else { 1026650997f4SStefano Zampini ierr = VecDuplicate(v2,&temp_vec);CHKERRQ(ierr); 1027650997f4SStefano Zampini ierr = MatMult(A,v1,temp_vec);CHKERRQ(ierr); 1028650997f4SStefano Zampini ierr = VecAXPY(temp_vec,1.0,v2);CHKERRQ(ierr); 1029650997f4SStefano Zampini ierr = VecCopy(temp_vec,v3);CHKERRQ(ierr); 1030650997f4SStefano Zampini ierr = VecDestroy(&temp_vec);CHKERRQ(ierr); 1031650997f4SStefano Zampini } 10322e74eeadSLisandro Dalcin PetscFunctionReturn(0); 10332e74eeadSLisandro Dalcin } 10342e74eeadSLisandro Dalcin 10352e74eeadSLisandro Dalcin #undef __FUNCT__ 10362e74eeadSLisandro Dalcin #define __FUNCT__ "MatMultTranspose_IS" 1037a8116848SStefano Zampini static PetscErrorCode MatMultTranspose_IS(Mat A,Vec y,Vec x) 10382e74eeadSLisandro Dalcin { 10392e74eeadSLisandro Dalcin Mat_IS *is = (Mat_IS*)A->data; 10402e74eeadSLisandro Dalcin PetscErrorCode ierr; 10412e74eeadSLisandro Dalcin 1042e176bc59SStefano Zampini PetscFunctionBegin; 10432e74eeadSLisandro Dalcin /* scatter the global vector x into the local work vector */ 1044e176bc59SStefano Zampini ierr = VecScatterBegin(is->rctx,y,is->y,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1045e176bc59SStefano Zampini ierr = VecScatterEnd(is->rctx,y,is->y,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 10462e74eeadSLisandro Dalcin 10472e74eeadSLisandro Dalcin /* multiply the local matrix */ 1048e176bc59SStefano Zampini ierr = MatMultTranspose(is->A,is->y,is->x);CHKERRQ(ierr); 10492e74eeadSLisandro Dalcin 10502e74eeadSLisandro Dalcin /* scatter product back into global vector */ 1051e176bc59SStefano Zampini ierr = VecSet(x,0);CHKERRQ(ierr); 1052e176bc59SStefano Zampini ierr = VecScatterBegin(is->cctx,is->x,x,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 1053e176bc59SStefano Zampini ierr = VecScatterEnd(is->cctx,is->x,x,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 10542e74eeadSLisandro Dalcin PetscFunctionReturn(0); 10552e74eeadSLisandro Dalcin } 10562e74eeadSLisandro Dalcin 10572e74eeadSLisandro Dalcin #undef __FUNCT__ 10582e74eeadSLisandro Dalcin #define __FUNCT__ "MatMultTransposeAdd_IS" 1059a8116848SStefano Zampini static PetscErrorCode MatMultTransposeAdd_IS(Mat A,Vec v1,Vec v2,Vec v3) 10602e74eeadSLisandro Dalcin { 1061650997f4SStefano Zampini Vec temp_vec; 10622e74eeadSLisandro Dalcin PetscErrorCode ierr; 10632e74eeadSLisandro Dalcin 10642e74eeadSLisandro Dalcin PetscFunctionBegin; /* v3 = v2 + A' * v1.*/ 1065650997f4SStefano Zampini if (v3 != v2) { 1066650997f4SStefano Zampini ierr = MatMultTranspose(A,v1,v3);CHKERRQ(ierr); 1067650997f4SStefano Zampini ierr = VecAXPY(v3,1.0,v2);CHKERRQ(ierr); 1068650997f4SStefano Zampini } else { 1069650997f4SStefano Zampini ierr = VecDuplicate(v2,&temp_vec);CHKERRQ(ierr); 1070650997f4SStefano Zampini ierr = MatMultTranspose(A,v1,temp_vec);CHKERRQ(ierr); 1071650997f4SStefano Zampini ierr = VecAXPY(temp_vec,1.0,v2);CHKERRQ(ierr); 1072650997f4SStefano Zampini ierr = VecCopy(temp_vec,v3);CHKERRQ(ierr); 1073650997f4SStefano Zampini ierr = VecDestroy(&temp_vec);CHKERRQ(ierr); 1074650997f4SStefano Zampini } 10752e74eeadSLisandro Dalcin PetscFunctionReturn(0); 10762e74eeadSLisandro Dalcin } 10772e74eeadSLisandro Dalcin 10782e74eeadSLisandro Dalcin #undef __FUNCT__ 1079b4319ba4SBarry Smith #define __FUNCT__ "MatView_IS" 1080a8116848SStefano Zampini static PetscErrorCode MatView_IS(Mat A,PetscViewer viewer) 1081b4319ba4SBarry Smith { 1082b4319ba4SBarry Smith Mat_IS *a = (Mat_IS*)A->data; 1083dfbe8321SBarry Smith PetscErrorCode ierr; 1084b4319ba4SBarry Smith PetscViewer sviewer; 1085b4319ba4SBarry Smith 1086b4319ba4SBarry Smith PetscFunctionBegin; 10873f08860eSBarry Smith ierr = PetscViewerGetSubViewer(viewer,PETSC_COMM_SELF,&sviewer);CHKERRQ(ierr); 1088b4319ba4SBarry Smith ierr = MatView(a->A,sviewer);CHKERRQ(ierr); 10893f08860eSBarry Smith ierr = PetscViewerRestoreSubViewer(viewer,PETSC_COMM_SELF,&sviewer);CHKERRQ(ierr); 10906e520ac8SStefano Zampini ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 1091b4319ba4SBarry Smith PetscFunctionReturn(0); 1092b4319ba4SBarry Smith } 1093b4319ba4SBarry Smith 1094b4319ba4SBarry Smith #undef __FUNCT__ 1095b4319ba4SBarry Smith #define __FUNCT__ "MatSetLocalToGlobalMapping_IS" 1096a8116848SStefano Zampini static PetscErrorCode MatSetLocalToGlobalMapping_IS(Mat A,ISLocalToGlobalMapping rmapping,ISLocalToGlobalMapping cmapping) 1097b4319ba4SBarry Smith { 1098dfbe8321SBarry Smith PetscErrorCode ierr; 1099e176bc59SStefano Zampini PetscInt nr,rbs,nc,cbs; 1100b4319ba4SBarry Smith Mat_IS *is = (Mat_IS*)A->data; 1101b4319ba4SBarry Smith IS from,to; 1102e176bc59SStefano Zampini Vec cglobal,rglobal; 1103b4319ba4SBarry Smith 1104b4319ba4SBarry Smith PetscFunctionBegin; 1105784ac674SJed Brown PetscCheckSameComm(A,1,rmapping,2); 1106e176bc59SStefano Zampini PetscCheckSameComm(A,1,cmapping,3); 11073bbff08aSStefano Zampini /* Destroy any previous data */ 110870cf5478SStefano Zampini ierr = VecDestroy(&is->x);CHKERRQ(ierr); 110970cf5478SStefano Zampini ierr = VecDestroy(&is->y);CHKERRQ(ierr); 11103fd1c9e7SStefano Zampini ierr = VecDestroy(&is->counter);CHKERRQ(ierr); 1111e176bc59SStefano Zampini ierr = VecScatterDestroy(&is->rctx);CHKERRQ(ierr); 1112e176bc59SStefano Zampini ierr = VecScatterDestroy(&is->cctx);CHKERRQ(ierr); 11131c47cb0fSStefano Zampini ierr = MatDestroy(&is->A);CHKERRQ(ierr); 111428f4e0baSStefano Zampini ierr = PetscSFDestroy(&is->sf);CHKERRQ(ierr); 111528f4e0baSStefano Zampini ierr = PetscFree2(is->sf_rootdata,is->sf_leafdata);CHKERRQ(ierr); 11163bbff08aSStefano Zampini 11173bbff08aSStefano Zampini /* Setup Layout and set local to global maps */ 1118fc27028aSStefano Zampini ierr = PetscLayoutSetUp(A->rmap);CHKERRQ(ierr); 1119fc27028aSStefano Zampini ierr = PetscLayoutSetUp(A->cmap);CHKERRQ(ierr); 1120fa7f1dd8SStefano Zampini ierr = PetscLayoutSetISLocalToGlobalMapping(A->rmap,rmapping);CHKERRQ(ierr); 1121fa7f1dd8SStefano Zampini ierr = PetscLayoutSetISLocalToGlobalMapping(A->cmap,cmapping);CHKERRQ(ierr); 1122b4319ba4SBarry Smith 1123b4319ba4SBarry Smith /* Create the local matrix A */ 1124e176bc59SStefano Zampini ierr = ISLocalToGlobalMappingGetSize(rmapping,&nr);CHKERRQ(ierr); 1125e176bc59SStefano Zampini ierr = ISLocalToGlobalMappingGetBlockSize(rmapping,&rbs);CHKERRQ(ierr); 1126e176bc59SStefano Zampini ierr = ISLocalToGlobalMappingGetSize(cmapping,&nc);CHKERRQ(ierr); 1127e176bc59SStefano Zampini ierr = ISLocalToGlobalMappingGetBlockSize(cmapping,&cbs);CHKERRQ(ierr); 1128f69a0ea3SMatthew Knepley ierr = MatCreate(PETSC_COMM_SELF,&is->A);CHKERRQ(ierr); 1129e176bc59SStefano Zampini ierr = MatSetType(is->A,MATAIJ);CHKERRQ(ierr); 1130e176bc59SStefano Zampini ierr = MatSetSizes(is->A,nr,nc,nr,nc);CHKERRQ(ierr); 1131e176bc59SStefano Zampini ierr = MatSetBlockSizes(is->A,rbs,cbs);CHKERRQ(ierr); 1132ff130e51SJed Brown ierr = MatSetOptionsPrefix(is->A,((PetscObject)A)->prefix);CHKERRQ(ierr); 1133ff130e51SJed Brown ierr = MatAppendOptionsPrefix(is->A,"is_");CHKERRQ(ierr); 1134b4319ba4SBarry Smith ierr = MatSetFromOptions(is->A);CHKERRQ(ierr); 1135b4319ba4SBarry Smith 1136f26d0771SStefano Zampini if (!is->islocalref) { /* setup scatters and local vectors for MatMult */ 1137b4319ba4SBarry Smith /* Create the local work vectors */ 11383bbff08aSStefano Zampini ierr = MatCreateVecs(is->A,&is->x,&is->y);CHKERRQ(ierr); 1139b4319ba4SBarry Smith 1140e176bc59SStefano Zampini /* setup the global to local scatters */ 1141e176bc59SStefano Zampini ierr = MatCreateVecs(A,&cglobal,&rglobal);CHKERRQ(ierr); 1142e176bc59SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,nr,0,1,&to);CHKERRQ(ierr); 1143784ac674SJed Brown ierr = ISLocalToGlobalMappingApplyIS(rmapping,to,&from);CHKERRQ(ierr); 1144e176bc59SStefano Zampini ierr = VecScatterCreate(rglobal,from,is->y,to,&is->rctx);CHKERRQ(ierr); 1145e176bc59SStefano Zampini if (rmapping != cmapping) { 1146e176bc59SStefano Zampini ierr = ISDestroy(&to);CHKERRQ(ierr); 1147e176bc59SStefano Zampini ierr = ISDestroy(&from);CHKERRQ(ierr); 1148e176bc59SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,nc,0,1,&to);CHKERRQ(ierr); 1149e176bc59SStefano Zampini ierr = ISLocalToGlobalMappingApplyIS(cmapping,to,&from);CHKERRQ(ierr); 1150e176bc59SStefano Zampini ierr = VecScatterCreate(cglobal,from,is->x,to,&is->cctx);CHKERRQ(ierr); 1151e176bc59SStefano Zampini } else { 1152e176bc59SStefano Zampini ierr = PetscObjectReference((PetscObject)is->rctx);CHKERRQ(ierr); 1153e176bc59SStefano Zampini is->cctx = is->rctx; 1154e176bc59SStefano Zampini } 11553fd1c9e7SStefano Zampini 11563fd1c9e7SStefano Zampini /* interface counter vector (local) */ 11573fd1c9e7SStefano Zampini ierr = VecDuplicate(is->y,&is->counter);CHKERRQ(ierr); 11583fd1c9e7SStefano Zampini ierr = VecSet(is->y,1.);CHKERRQ(ierr); 11593fd1c9e7SStefano Zampini ierr = VecScatterBegin(is->rctx,is->y,rglobal,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 11603fd1c9e7SStefano Zampini ierr = VecScatterEnd(is->rctx,is->y,rglobal,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 11613fd1c9e7SStefano Zampini ierr = VecScatterBegin(is->rctx,rglobal,is->counter,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 11623fd1c9e7SStefano Zampini ierr = VecScatterEnd(is->rctx,rglobal,is->counter,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 11633fd1c9e7SStefano Zampini 11643fd1c9e7SStefano Zampini /* free workspace */ 1165e176bc59SStefano Zampini ierr = VecDestroy(&rglobal);CHKERRQ(ierr); 1166e176bc59SStefano Zampini ierr = VecDestroy(&cglobal);CHKERRQ(ierr); 11676bf464f9SBarry Smith ierr = ISDestroy(&to);CHKERRQ(ierr); 11686bf464f9SBarry Smith ierr = ISDestroy(&from);CHKERRQ(ierr); 1169f26d0771SStefano Zampini } 117048ff6bf3SStefano Zampini ierr = MatSetUp(A);CHKERRQ(ierr); 1171b4319ba4SBarry Smith PetscFunctionReturn(0); 1172b4319ba4SBarry Smith } 1173b4319ba4SBarry Smith 11742e74eeadSLisandro Dalcin #undef __FUNCT__ 11752e74eeadSLisandro Dalcin #define __FUNCT__ "MatSetValues_IS" 1176a8116848SStefano Zampini static PetscErrorCode MatSetValues_IS(Mat mat, PetscInt m,const PetscInt *rows, PetscInt n,const PetscInt *cols, const PetscScalar *values, InsertMode addv) 11772e74eeadSLisandro Dalcin { 11782e74eeadSLisandro Dalcin Mat_IS *is = (Mat_IS*)mat->data; 11792e74eeadSLisandro Dalcin PetscErrorCode ierr; 118097563a80SStefano Zampini #if defined(PETSC_USE_DEBUG) 118197563a80SStefano Zampini PetscInt i,zm,zn; 118297563a80SStefano Zampini #endif 1183f26d0771SStefano Zampini PetscInt rows_l[MATIS_MAX_ENTRIES_INSERTION],cols_l[MATIS_MAX_ENTRIES_INSERTION]; 11842e74eeadSLisandro Dalcin 11852e74eeadSLisandro Dalcin PetscFunctionBegin; 11862e74eeadSLisandro Dalcin #if defined(PETSC_USE_DEBUG) 1187f26d0771SStefano 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); 118897563a80SStefano Zampini /* count negative indices */ 118997563a80SStefano Zampini for (i=0,zm=0;i<m;i++) if (rows[i] < 0) zm++; 119097563a80SStefano Zampini for (i=0,zn=0;i<n;i++) if (cols[i] < 0) zn++; 11912e74eeadSLisandro Dalcin #endif 119297563a80SStefano Zampini ierr = ISGlobalToLocalMappingApply(mat->rmap->mapping,IS_GTOLM_MASK,m,rows,&m,rows_l);CHKERRQ(ierr); 119397563a80SStefano Zampini ierr = ISGlobalToLocalMappingApply(mat->cmap->mapping,IS_GTOLM_MASK,n,cols,&n,cols_l);CHKERRQ(ierr); 119497563a80SStefano Zampini #if defined(PETSC_USE_DEBUG) 119597563a80SStefano Zampini /* count negative indices (should be the same as before) */ 119697563a80SStefano Zampini for (i=0;i<m;i++) if (rows_l[i] < 0) zm--; 119797563a80SStefano Zampini for (i=0;i<n;i++) if (cols_l[i] < 0) zn--; 119897563a80SStefano 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"); 119997563a80SStefano 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"); 120097563a80SStefano Zampini #endif 12012e74eeadSLisandro Dalcin ierr = MatSetValues(is->A,m,rows_l,n,cols_l,values,addv);CHKERRQ(ierr); 12022e74eeadSLisandro Dalcin PetscFunctionReturn(0); 12032e74eeadSLisandro Dalcin } 12042e74eeadSLisandro Dalcin 1205b4319ba4SBarry Smith #undef __FUNCT__ 120697563a80SStefano Zampini #define __FUNCT__ "MatSetValuesBlocked_IS" 1207a8116848SStefano Zampini static PetscErrorCode MatSetValuesBlocked_IS(Mat mat, PetscInt m,const PetscInt *rows, PetscInt n,const PetscInt *cols, const PetscScalar *values, InsertMode addv) 120897563a80SStefano Zampini { 120997563a80SStefano Zampini Mat_IS *is = (Mat_IS*)mat->data; 121097563a80SStefano Zampini PetscErrorCode ierr; 121197563a80SStefano Zampini #if defined(PETSC_USE_DEBUG) 121297563a80SStefano Zampini PetscInt i,zm,zn; 121397563a80SStefano Zampini #endif 1214f26d0771SStefano Zampini PetscInt rows_l[MATIS_MAX_ENTRIES_INSERTION],cols_l[MATIS_MAX_ENTRIES_INSERTION]; 121597563a80SStefano Zampini 121697563a80SStefano Zampini PetscFunctionBegin; 121797563a80SStefano Zampini #if defined(PETSC_USE_DEBUG) 1218f26d0771SStefano 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); 121997563a80SStefano Zampini /* count negative indices */ 122097563a80SStefano Zampini for (i=0,zm=0;i<m;i++) if (rows[i] < 0) zm++; 122197563a80SStefano Zampini for (i=0,zn=0;i<n;i++) if (cols[i] < 0) zn++; 122297563a80SStefano Zampini #endif 122397563a80SStefano Zampini ierr = ISGlobalToLocalMappingApplyBlock(mat->rmap->mapping,IS_GTOLM_MASK,m,rows,&m,rows_l);CHKERRQ(ierr); 122497563a80SStefano Zampini ierr = ISGlobalToLocalMappingApplyBlock(mat->cmap->mapping,IS_GTOLM_MASK,n,cols,&n,cols_l);CHKERRQ(ierr); 122597563a80SStefano Zampini #if defined(PETSC_USE_DEBUG) 122697563a80SStefano Zampini /* count negative indices (should be the same as before) */ 122797563a80SStefano Zampini for (i=0;i<m;i++) if (rows_l[i] < 0) zm--; 122897563a80SStefano Zampini for (i=0;i<n;i++) if (cols_l[i] < 0) zn--; 122997563a80SStefano 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"); 123097563a80SStefano 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"); 123197563a80SStefano Zampini #endif 123297563a80SStefano Zampini ierr = MatSetValuesBlocked(is->A,m,rows_l,n,cols_l,values,addv);CHKERRQ(ierr); 123397563a80SStefano Zampini PetscFunctionReturn(0); 123497563a80SStefano Zampini } 123597563a80SStefano Zampini 123697563a80SStefano Zampini #undef __FUNCT__ 1237b4319ba4SBarry Smith #define __FUNCT__ "MatSetValuesLocal_IS" 1238a8116848SStefano Zampini static PetscErrorCode MatSetValuesLocal_IS(Mat A,PetscInt m,const PetscInt *rows, PetscInt n,const PetscInt *cols,const PetscScalar *values,InsertMode addv) 1239b4319ba4SBarry Smith { 1240dfbe8321SBarry Smith PetscErrorCode ierr; 1241b4319ba4SBarry Smith Mat_IS *is = (Mat_IS*)A->data; 1242b4319ba4SBarry Smith 1243b4319ba4SBarry Smith PetscFunctionBegin; 1244b4319ba4SBarry Smith ierr = MatSetValues(is->A,m,rows,n,cols,values,addv);CHKERRQ(ierr); 1245b4319ba4SBarry Smith PetscFunctionReturn(0); 1246b4319ba4SBarry Smith } 1247b4319ba4SBarry Smith 1248b4319ba4SBarry Smith #undef __FUNCT__ 1249f0006bf2SLisandro Dalcin #define __FUNCT__ "MatSetValuesBlockedLocal_IS" 1250a8116848SStefano Zampini static PetscErrorCode MatSetValuesBlockedLocal_IS(Mat A,PetscInt m,const PetscInt *rows, PetscInt n,const PetscInt *cols,const PetscScalar *values,InsertMode addv) 1251f0006bf2SLisandro Dalcin { 1252f0006bf2SLisandro Dalcin PetscErrorCode ierr; 1253f0006bf2SLisandro Dalcin Mat_IS *is = (Mat_IS*)A->data; 1254f0006bf2SLisandro Dalcin 1255f0006bf2SLisandro Dalcin PetscFunctionBegin; 1256f0006bf2SLisandro Dalcin ierr = MatSetValuesBlocked(is->A,m,rows,n,cols,values,addv);CHKERRQ(ierr); 1257f0006bf2SLisandro Dalcin PetscFunctionReturn(0); 1258f0006bf2SLisandro Dalcin } 1259f0006bf2SLisandro Dalcin 1260f0006bf2SLisandro Dalcin #undef __FUNCT__ 1261f0ae7da4SStefano Zampini #define __FUNCT__ "MatISZeroRowsColumnsLocal_Private" 1262f0ae7da4SStefano Zampini static PetscErrorCode MatISZeroRowsColumnsLocal_Private(Mat A,PetscInt n,const PetscInt rows[],PetscScalar diag,PetscBool columns) 1263f0ae7da4SStefano Zampini { 1264f0ae7da4SStefano Zampini Mat_IS *is = (Mat_IS*)A->data; 1265f0ae7da4SStefano Zampini PetscErrorCode ierr; 1266f0ae7da4SStefano Zampini 1267f0ae7da4SStefano Zampini PetscFunctionBegin; 1268f0ae7da4SStefano Zampini if (!n) { 1269f0ae7da4SStefano Zampini is->pure_neumann = PETSC_TRUE; 1270f0ae7da4SStefano Zampini } else { 1271f0ae7da4SStefano Zampini PetscInt i; 1272f0ae7da4SStefano Zampini is->pure_neumann = PETSC_FALSE; 1273f0ae7da4SStefano Zampini 1274f0ae7da4SStefano Zampini if (columns) { 1275f0ae7da4SStefano Zampini ierr = MatZeroRowsColumns(is->A,n,rows,diag,0,0);CHKERRQ(ierr); 1276f0ae7da4SStefano Zampini } else { 1277f0ae7da4SStefano Zampini ierr = MatZeroRows(is->A,n,rows,diag,0,0);CHKERRQ(ierr); 1278f0ae7da4SStefano Zampini } 1279f0ae7da4SStefano Zampini if (diag != 0.) { 1280f0ae7da4SStefano Zampini const PetscScalar *array; 1281f0ae7da4SStefano Zampini ierr = VecGetArrayRead(is->counter,&array);CHKERRQ(ierr); 1282f0ae7da4SStefano Zampini for (i=0; i<n; i++) { 1283f0ae7da4SStefano Zampini ierr = MatSetValue(is->A,rows[i],rows[i],diag/(array[rows[i]]),INSERT_VALUES);CHKERRQ(ierr); 1284f0ae7da4SStefano Zampini } 1285f0ae7da4SStefano Zampini ierr = VecRestoreArrayRead(is->counter,&array);CHKERRQ(ierr); 1286f0ae7da4SStefano Zampini } 1287f0ae7da4SStefano Zampini ierr = MatAssemblyBegin(is->A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1288f0ae7da4SStefano Zampini ierr = MatAssemblyEnd(is->A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1289f0ae7da4SStefano Zampini } 1290f0ae7da4SStefano Zampini PetscFunctionReturn(0); 1291f0ae7da4SStefano Zampini } 1292f0ae7da4SStefano Zampini 1293f0ae7da4SStefano Zampini #undef __FUNCT__ 1294f0ae7da4SStefano Zampini #define __FUNCT__ "MatZeroRowsColumns_Private_IS" 1295f0ae7da4SStefano Zampini static PetscErrorCode MatZeroRowsColumns_Private_IS(Mat A,PetscInt n,const PetscInt rows[],PetscScalar diag,Vec x,Vec b,PetscBool columns) 12962e74eeadSLisandro Dalcin { 12976e520ac8SStefano Zampini Mat_IS *matis = (Mat_IS*)A->data; 12986e520ac8SStefano Zampini PetscInt nr,nl,len,i; 12996e520ac8SStefano Zampini PetscInt *lrows; 13002e74eeadSLisandro Dalcin PetscErrorCode ierr; 13012e74eeadSLisandro Dalcin 13022e74eeadSLisandro Dalcin PetscFunctionBegin; 1303f0ae7da4SStefano Zampini #if defined(PETSC_USE_DEBUG) 1304f0ae7da4SStefano Zampini if (columns || diag != 0. || (x && b)) { 1305f0ae7da4SStefano Zampini PetscBool cong; 1306f0ae7da4SStefano Zampini ierr = PetscLayoutCompare(A->rmap,A->cmap,&cong);CHKERRQ(ierr); 1307f0ae7da4SStefano 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"); 1308f0ae7da4SStefano 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"); 1309f0ae7da4SStefano Zampini if (!cong && x && b) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"A->rmap and A->cmap need to be congruent"); 1310f0ae7da4SStefano Zampini } 1311f0ae7da4SStefano Zampini #endif 13126e520ac8SStefano Zampini /* get locally owned rows */ 1313f0ae7da4SStefano Zampini ierr = PetscLayoutMapLocal_Private(A->rmap,n,rows,&len,&lrows,NULL);CHKERRQ(ierr); 13146e520ac8SStefano Zampini /* fix right hand side if needed */ 13156e520ac8SStefano Zampini if (x && b) { 13166e520ac8SStefano Zampini const PetscScalar *xx; 13176e520ac8SStefano Zampini PetscScalar *bb; 13186e520ac8SStefano Zampini 13196e520ac8SStefano Zampini ierr = VecGetArrayRead(x, &xx);CHKERRQ(ierr); 13206e520ac8SStefano Zampini ierr = VecGetArray(b, &bb);CHKERRQ(ierr); 13216e520ac8SStefano Zampini for (i=0;i<len;++i) bb[lrows[i]] = diag*xx[lrows[i]]; 13226e520ac8SStefano Zampini ierr = VecRestoreArrayRead(x, &xx);CHKERRQ(ierr); 13236e520ac8SStefano Zampini ierr = VecRestoreArray(b, &bb);CHKERRQ(ierr); 13242e74eeadSLisandro Dalcin } 13256e520ac8SStefano Zampini /* get rows associated to the local matrices */ 13266e520ac8SStefano Zampini if (!matis->sf) { /* setup SF if not yet created and allocate rootdata and leafdata */ 13276e520ac8SStefano Zampini ierr = MatISComputeSF_Private(A);CHKERRQ(ierr); 13286e520ac8SStefano Zampini } 13296e520ac8SStefano Zampini ierr = MatGetSize(matis->A,&nl,NULL);CHKERRQ(ierr); 13306e520ac8SStefano Zampini ierr = PetscMemzero(matis->sf_leafdata,nl*sizeof(PetscInt));CHKERRQ(ierr); 13316e520ac8SStefano Zampini ierr = PetscMemzero(matis->sf_rootdata,A->rmap->n*sizeof(PetscInt));CHKERRQ(ierr); 13326e520ac8SStefano Zampini for (i=0;i<len;i++) matis->sf_rootdata[lrows[i]] = 1; 13336e520ac8SStefano Zampini ierr = PetscFree(lrows);CHKERRQ(ierr); 13346e520ac8SStefano Zampini ierr = PetscSFBcastBegin(matis->sf,MPIU_INT,matis->sf_rootdata,matis->sf_leafdata);CHKERRQ(ierr); 13356e520ac8SStefano Zampini ierr = PetscSFBcastEnd(matis->sf,MPIU_INT,matis->sf_rootdata,matis->sf_leafdata);CHKERRQ(ierr); 13366e520ac8SStefano Zampini ierr = PetscMalloc1(nl,&lrows);CHKERRQ(ierr); 13376e520ac8SStefano Zampini for (i=0,nr=0;i<nl;i++) if (matis->sf_leafdata[i]) lrows[nr++] = i; 1338f0ae7da4SStefano Zampini ierr = MatISZeroRowsColumnsLocal_Private(A,nr,lrows,diag,columns);CHKERRQ(ierr); 13396e520ac8SStefano Zampini ierr = PetscFree(lrows);CHKERRQ(ierr); 13402e74eeadSLisandro Dalcin PetscFunctionReturn(0); 13412e74eeadSLisandro Dalcin } 13422e74eeadSLisandro Dalcin 13432e74eeadSLisandro Dalcin #undef __FUNCT__ 1344f0ae7da4SStefano Zampini #define __FUNCT__ "MatZeroRows_IS" 1345f0ae7da4SStefano Zampini static PetscErrorCode MatZeroRows_IS(Mat A,PetscInt n,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 1346b4319ba4SBarry Smith { 1347dfbe8321SBarry Smith PetscErrorCode ierr; 1348b4319ba4SBarry Smith 1349b4319ba4SBarry Smith PetscFunctionBegin; 1350f0ae7da4SStefano Zampini ierr = MatZeroRowsColumns_Private_IS(A,n,rows,diag,x,b,PETSC_FALSE);CHKERRQ(ierr); 1351f0ae7da4SStefano Zampini PetscFunctionReturn(0); 1352f0ae7da4SStefano Zampini } 13532205254eSKarl Rupp 1354f0ae7da4SStefano Zampini #undef __FUNCT__ 1355f0ae7da4SStefano Zampini #define __FUNCT__ "MatZeroRowsColumns_IS" 1356f0ae7da4SStefano Zampini static PetscErrorCode MatZeroRowsColumns_IS(Mat A,PetscInt n,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 1357f0ae7da4SStefano Zampini { 1358f0ae7da4SStefano Zampini PetscErrorCode ierr; 1359f0ae7da4SStefano Zampini 1360f0ae7da4SStefano Zampini PetscFunctionBegin; 1361f0ae7da4SStefano Zampini ierr = MatZeroRowsColumns_Private_IS(A,n,rows,diag,x,b,PETSC_TRUE);CHKERRQ(ierr); 1362b4319ba4SBarry Smith PetscFunctionReturn(0); 1363b4319ba4SBarry Smith } 1364b4319ba4SBarry Smith 1365b4319ba4SBarry Smith #undef __FUNCT__ 1366b4319ba4SBarry Smith #define __FUNCT__ "MatAssemblyBegin_IS" 1367a8116848SStefano Zampini static PetscErrorCode MatAssemblyBegin_IS(Mat A,MatAssemblyType type) 1368b4319ba4SBarry Smith { 1369b4319ba4SBarry Smith Mat_IS *is = (Mat_IS*)A->data; 1370dfbe8321SBarry Smith PetscErrorCode ierr; 1371b4319ba4SBarry Smith 1372b4319ba4SBarry Smith PetscFunctionBegin; 1373b4319ba4SBarry Smith ierr = MatAssemblyBegin(is->A,type);CHKERRQ(ierr); 1374b4319ba4SBarry Smith PetscFunctionReturn(0); 1375b4319ba4SBarry Smith } 1376b4319ba4SBarry Smith 1377b4319ba4SBarry Smith #undef __FUNCT__ 1378b4319ba4SBarry Smith #define __FUNCT__ "MatAssemblyEnd_IS" 1379a8116848SStefano Zampini static PetscErrorCode MatAssemblyEnd_IS(Mat A,MatAssemblyType type) 1380b4319ba4SBarry Smith { 1381b4319ba4SBarry Smith Mat_IS *is = (Mat_IS*)A->data; 1382dfbe8321SBarry Smith PetscErrorCode ierr; 1383b4319ba4SBarry Smith 1384b4319ba4SBarry Smith PetscFunctionBegin; 1385b4319ba4SBarry Smith ierr = MatAssemblyEnd(is->A,type);CHKERRQ(ierr); 1386b4319ba4SBarry Smith PetscFunctionReturn(0); 1387b4319ba4SBarry Smith } 1388b4319ba4SBarry Smith 1389b4319ba4SBarry Smith #undef __FUNCT__ 1390b4319ba4SBarry Smith #define __FUNCT__ "MatISGetLocalMat_IS" 1391a8116848SStefano Zampini static PetscErrorCode MatISGetLocalMat_IS(Mat mat,Mat *local) 1392b4319ba4SBarry Smith { 1393b4319ba4SBarry Smith Mat_IS *is = (Mat_IS*)mat->data; 1394b4319ba4SBarry Smith 1395b4319ba4SBarry Smith PetscFunctionBegin; 1396b4319ba4SBarry Smith *local = is->A; 1397b4319ba4SBarry Smith PetscFunctionReturn(0); 1398b4319ba4SBarry Smith } 1399b4319ba4SBarry Smith 1400b4319ba4SBarry Smith #undef __FUNCT__ 1401b4319ba4SBarry Smith #define __FUNCT__ "MatISGetLocalMat" 1402b4319ba4SBarry Smith /*@ 1403b4319ba4SBarry Smith MatISGetLocalMat - Gets the local matrix stored inside a MATIS matrix. 1404b4319ba4SBarry Smith 1405b4319ba4SBarry Smith Input Parameter: 1406b4319ba4SBarry Smith . mat - the matrix 1407b4319ba4SBarry Smith 1408b4319ba4SBarry Smith Output Parameter: 1409eb82efa4SStefano Zampini . local - the local matrix 1410b4319ba4SBarry Smith 1411b4319ba4SBarry Smith Level: advanced 1412b4319ba4SBarry Smith 1413b4319ba4SBarry Smith Notes: 1414b4319ba4SBarry Smith This can be called if you have precomputed the nonzero structure of the 1415b4319ba4SBarry Smith matrix and want to provide it to the inner matrix object to improve the performance 1416b4319ba4SBarry Smith of the MatSetValues() operation. 1417b4319ba4SBarry Smith 1418b4319ba4SBarry Smith .seealso: MATIS 1419b4319ba4SBarry Smith @*/ 14207087cfbeSBarry Smith PetscErrorCode MatISGetLocalMat(Mat mat,Mat *local) 1421b4319ba4SBarry Smith { 14224ac538c5SBarry Smith PetscErrorCode ierr; 1423b4319ba4SBarry Smith 1424b4319ba4SBarry Smith PetscFunctionBegin; 14250700a824SBarry Smith PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1426b4319ba4SBarry Smith PetscValidPointer(local,2); 14274ac538c5SBarry Smith ierr = PetscUseMethod(mat,"MatISGetLocalMat_C",(Mat,Mat*),(mat,local));CHKERRQ(ierr); 1428b4319ba4SBarry Smith PetscFunctionReturn(0); 1429b4319ba4SBarry Smith } 1430b4319ba4SBarry Smith 14313b03a366Sstefano_zampini #undef __FUNCT__ 14323b03a366Sstefano_zampini #define __FUNCT__ "MatISSetLocalMat_IS" 1433a8116848SStefano Zampini static PetscErrorCode MatISSetLocalMat_IS(Mat mat,Mat local) 14343b03a366Sstefano_zampini { 14353b03a366Sstefano_zampini Mat_IS *is = (Mat_IS*)mat->data; 14363b03a366Sstefano_zampini PetscInt nrows,ncols,orows,ocols; 14373b03a366Sstefano_zampini PetscErrorCode ierr; 14383b03a366Sstefano_zampini 14393b03a366Sstefano_zampini PetscFunctionBegin; 14404e4c7dbeSStefano Zampini if (is->A) { 14413b03a366Sstefano_zampini ierr = MatGetSize(is->A,&orows,&ocols);CHKERRQ(ierr); 14423b03a366Sstefano_zampini ierr = MatGetSize(local,&nrows,&ncols);CHKERRQ(ierr); 1443f0ae7da4SStefano 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); 14444e4c7dbeSStefano Zampini } 14453b03a366Sstefano_zampini ierr = PetscObjectReference((PetscObject)local);CHKERRQ(ierr); 14463b03a366Sstefano_zampini ierr = MatDestroy(&is->A);CHKERRQ(ierr); 14473b03a366Sstefano_zampini is->A = local; 14483b03a366Sstefano_zampini PetscFunctionReturn(0); 14493b03a366Sstefano_zampini } 14503b03a366Sstefano_zampini 14513b03a366Sstefano_zampini #undef __FUNCT__ 14523b03a366Sstefano_zampini #define __FUNCT__ "MatISSetLocalMat" 14533b03a366Sstefano_zampini /*@ 1454eb82efa4SStefano Zampini MatISSetLocalMat - Replace the local matrix stored inside a MATIS object. 14553b03a366Sstefano_zampini 14563b03a366Sstefano_zampini Input Parameter: 14573b03a366Sstefano_zampini . mat - the matrix 1458eb82efa4SStefano Zampini . local - the local matrix 14593b03a366Sstefano_zampini 14603b03a366Sstefano_zampini Output Parameter: 14613b03a366Sstefano_zampini 14623b03a366Sstefano_zampini Level: advanced 14633b03a366Sstefano_zampini 14643b03a366Sstefano_zampini Notes: 14653b03a366Sstefano_zampini This can be called if you have precomputed the local matrix and 14663b03a366Sstefano_zampini want to provide it to the matrix object MATIS. 14673b03a366Sstefano_zampini 14683b03a366Sstefano_zampini .seealso: MATIS 14693b03a366Sstefano_zampini @*/ 14703b03a366Sstefano_zampini PetscErrorCode MatISSetLocalMat(Mat mat,Mat local) 14713b03a366Sstefano_zampini { 14723b03a366Sstefano_zampini PetscErrorCode ierr; 14733b03a366Sstefano_zampini 14743b03a366Sstefano_zampini PetscFunctionBegin; 14753b03a366Sstefano_zampini PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1476b7ce53b6SStefano Zampini PetscValidHeaderSpecific(local,MAT_CLASSID,2); 14773b03a366Sstefano_zampini ierr = PetscUseMethod(mat,"MatISSetLocalMat_C",(Mat,Mat),(mat,local));CHKERRQ(ierr); 14783b03a366Sstefano_zampini PetscFunctionReturn(0); 14793b03a366Sstefano_zampini } 14803b03a366Sstefano_zampini 14816726f965SBarry Smith #undef __FUNCT__ 14826726f965SBarry Smith #define __FUNCT__ "MatZeroEntries_IS" 1483a8116848SStefano Zampini static PetscErrorCode MatZeroEntries_IS(Mat A) 14846726f965SBarry Smith { 14856726f965SBarry Smith Mat_IS *a = (Mat_IS*)A->data; 14866726f965SBarry Smith PetscErrorCode ierr; 14876726f965SBarry Smith 14886726f965SBarry Smith PetscFunctionBegin; 14896726f965SBarry Smith ierr = MatZeroEntries(a->A);CHKERRQ(ierr); 14906726f965SBarry Smith PetscFunctionReturn(0); 14916726f965SBarry Smith } 14926726f965SBarry Smith 14936726f965SBarry Smith #undef __FUNCT__ 14942e74eeadSLisandro Dalcin #define __FUNCT__ "MatScale_IS" 1495a8116848SStefano Zampini static PetscErrorCode MatScale_IS(Mat A,PetscScalar a) 14962e74eeadSLisandro Dalcin { 14972e74eeadSLisandro Dalcin Mat_IS *is = (Mat_IS*)A->data; 14982e74eeadSLisandro Dalcin PetscErrorCode ierr; 14992e74eeadSLisandro Dalcin 15002e74eeadSLisandro Dalcin PetscFunctionBegin; 15012e74eeadSLisandro Dalcin ierr = MatScale(is->A,a);CHKERRQ(ierr); 15022e74eeadSLisandro Dalcin PetscFunctionReturn(0); 15032e74eeadSLisandro Dalcin } 15042e74eeadSLisandro Dalcin 15052e74eeadSLisandro Dalcin #undef __FUNCT__ 15062e74eeadSLisandro Dalcin #define __FUNCT__ "MatGetDiagonal_IS" 1507a8116848SStefano Zampini static PetscErrorCode MatGetDiagonal_IS(Mat A, Vec v) 15082e74eeadSLisandro Dalcin { 15092e74eeadSLisandro Dalcin Mat_IS *is = (Mat_IS*)A->data; 15102e74eeadSLisandro Dalcin PetscErrorCode ierr; 15112e74eeadSLisandro Dalcin 15122e74eeadSLisandro Dalcin PetscFunctionBegin; 15132e74eeadSLisandro Dalcin /* get diagonal of the local matrix */ 1514e176bc59SStefano Zampini ierr = MatGetDiagonal(is->A,is->y);CHKERRQ(ierr); 15152e74eeadSLisandro Dalcin 15162e74eeadSLisandro Dalcin /* scatter diagonal back into global vector */ 15172e74eeadSLisandro Dalcin ierr = VecSet(v,0);CHKERRQ(ierr); 1518e176bc59SStefano Zampini ierr = VecScatterBegin(is->rctx,is->y,v,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 1519e176bc59SStefano Zampini ierr = VecScatterEnd(is->rctx,is->y,v,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 15202e74eeadSLisandro Dalcin PetscFunctionReturn(0); 15212e74eeadSLisandro Dalcin } 15222e74eeadSLisandro Dalcin 15232e74eeadSLisandro Dalcin #undef __FUNCT__ 15246726f965SBarry Smith #define __FUNCT__ "MatSetOption_IS" 1525a8116848SStefano Zampini static PetscErrorCode MatSetOption_IS(Mat A,MatOption op,PetscBool flg) 15266726f965SBarry Smith { 15276726f965SBarry Smith Mat_IS *a = (Mat_IS*)A->data; 15286726f965SBarry Smith PetscErrorCode ierr; 15296726f965SBarry Smith 15306726f965SBarry Smith PetscFunctionBegin; 15314e0d8c25SBarry Smith ierr = MatSetOption(a->A,op,flg);CHKERRQ(ierr); 15326726f965SBarry Smith PetscFunctionReturn(0); 15336726f965SBarry Smith } 15346726f965SBarry Smith 1535284134d9SBarry Smith #undef __FUNCT__ 1536f26d0771SStefano Zampini #define __FUNCT__ "MatAXPY_IS" 1537f26d0771SStefano Zampini static PetscErrorCode MatAXPY_IS(Mat Y,PetscScalar a,Mat X,MatStructure str) 1538f26d0771SStefano Zampini { 1539f26d0771SStefano Zampini Mat_IS *y = (Mat_IS*)Y->data; 1540f26d0771SStefano Zampini Mat_IS *x; 1541f26d0771SStefano Zampini #if defined(PETSC_USE_DEBUG) 1542f26d0771SStefano Zampini PetscBool ismatis; 1543f26d0771SStefano Zampini #endif 1544f26d0771SStefano Zampini PetscErrorCode ierr; 1545f26d0771SStefano Zampini 1546f26d0771SStefano Zampini PetscFunctionBegin; 1547f26d0771SStefano Zampini #if defined(PETSC_USE_DEBUG) 1548f26d0771SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)X,MATIS,&ismatis);CHKERRQ(ierr); 1549f26d0771SStefano Zampini if (!ismatis) SETERRQ(PetscObjectComm((PetscObject)Y),PETSC_ERR_SUP,"Cannot call MatAXPY(Y,a,X,str) with X not of type MATIS"); 1550f26d0771SStefano Zampini #endif 1551f26d0771SStefano Zampini x = (Mat_IS*)X->data; 1552f26d0771SStefano Zampini ierr = MatAXPY(y->A,a,x->A,str);CHKERRQ(ierr); 1553f26d0771SStefano Zampini PetscFunctionReturn(0); 1554f26d0771SStefano Zampini } 1555f26d0771SStefano Zampini 1556f26d0771SStefano Zampini #undef __FUNCT__ 1557f26d0771SStefano Zampini #define __FUNCT__ "MatGetLocalSubMatrix_IS" 1558f26d0771SStefano Zampini static PetscErrorCode MatGetLocalSubMatrix_IS(Mat A,IS row,IS col,Mat *submat) 1559f26d0771SStefano Zampini { 1560f26d0771SStefano Zampini Mat lA; 1561f26d0771SStefano Zampini Mat_IS *matis; 1562f26d0771SStefano Zampini ISLocalToGlobalMapping rl2g,cl2g; 1563f26d0771SStefano Zampini IS is; 1564f26d0771SStefano Zampini const PetscInt *rg,*rl; 1565f26d0771SStefano Zampini PetscInt nrg; 1566f26d0771SStefano Zampini PetscInt N,M,nrl,i,*idxs; 1567f26d0771SStefano Zampini PetscErrorCode ierr; 1568f26d0771SStefano Zampini 1569f26d0771SStefano Zampini PetscFunctionBegin; 1570f26d0771SStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(A->rmap->mapping,&rg);CHKERRQ(ierr); 1571f26d0771SStefano Zampini ierr = ISGetLocalSize(row,&nrl);CHKERRQ(ierr); 1572f26d0771SStefano Zampini ierr = ISGetIndices(row,&rl);CHKERRQ(ierr); 1573f26d0771SStefano Zampini ierr = ISLocalToGlobalMappingGetSize(A->rmap->mapping,&nrg);CHKERRQ(ierr); 1574f26d0771SStefano Zampini #if defined(PETSC_USE_DEBUG) 1575f0ae7da4SStefano 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); 1576f26d0771SStefano Zampini #endif 1577f26d0771SStefano Zampini ierr = PetscMalloc1(nrg,&idxs);CHKERRQ(ierr); 1578f26d0771SStefano Zampini /* map from [0,nrl) to row */ 1579f26d0771SStefano Zampini for (i=0;i<nrl;i++) idxs[i] = rl[i]; 1580f26d0771SStefano Zampini #if defined(PETSC_USE_DEBUG) 1581f26d0771SStefano Zampini for (i=nrl;i<nrg;i++) idxs[i] = nrg; 1582f26d0771SStefano Zampini #else 1583f26d0771SStefano Zampini for (i=nrl;i<nrg;i++) idxs[i] = -1; 1584f26d0771SStefano Zampini #endif 1585f26d0771SStefano Zampini ierr = ISRestoreIndices(row,&rl);CHKERRQ(ierr); 1586f26d0771SStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(A->rmap->mapping,&rg);CHKERRQ(ierr); 1587f26d0771SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)A),nrg,idxs,PETSC_OWN_POINTER,&is);CHKERRQ(ierr); 1588f26d0771SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is,&rl2g);CHKERRQ(ierr); 1589f26d0771SStefano Zampini ierr = ISDestroy(&is);CHKERRQ(ierr); 1590f26d0771SStefano Zampini /* compute new l2g map for columns */ 1591f26d0771SStefano Zampini if (col != row || A->rmap->mapping != A->cmap->mapping) { 1592f26d0771SStefano Zampini const PetscInt *cg,*cl; 1593f26d0771SStefano Zampini PetscInt ncg; 1594f26d0771SStefano Zampini PetscInt ncl; 1595f26d0771SStefano Zampini 1596f26d0771SStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(A->cmap->mapping,&cg);CHKERRQ(ierr); 1597f26d0771SStefano Zampini ierr = ISGetLocalSize(col,&ncl);CHKERRQ(ierr); 1598f26d0771SStefano Zampini ierr = ISGetIndices(col,&cl);CHKERRQ(ierr); 1599f26d0771SStefano Zampini ierr = ISLocalToGlobalMappingGetSize(A->cmap->mapping,&ncg);CHKERRQ(ierr); 1600f26d0771SStefano Zampini #if defined(PETSC_USE_DEBUG) 1601f0ae7da4SStefano 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); 1602f26d0771SStefano Zampini #endif 1603f26d0771SStefano Zampini ierr = PetscMalloc1(ncg,&idxs);CHKERRQ(ierr); 1604f26d0771SStefano Zampini /* map from [0,ncl) to col */ 1605f26d0771SStefano Zampini for (i=0;i<ncl;i++) idxs[i] = cl[i]; 1606f26d0771SStefano Zampini #if defined(PETSC_USE_DEBUG) 1607f26d0771SStefano Zampini for (i=ncl;i<ncg;i++) idxs[i] = ncg; 1608f26d0771SStefano Zampini #else 1609f26d0771SStefano Zampini for (i=ncl;i<ncg;i++) idxs[i] = -1; 1610f26d0771SStefano Zampini #endif 1611f26d0771SStefano Zampini ierr = ISRestoreIndices(col,&cl);CHKERRQ(ierr); 1612f26d0771SStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(A->cmap->mapping,&cg);CHKERRQ(ierr); 1613f26d0771SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)A),ncg,idxs,PETSC_OWN_POINTER,&is);CHKERRQ(ierr); 1614f26d0771SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is,&cl2g);CHKERRQ(ierr); 1615f26d0771SStefano Zampini ierr = ISDestroy(&is);CHKERRQ(ierr); 1616f26d0771SStefano Zampini } else { 1617f26d0771SStefano Zampini ierr = PetscObjectReference((PetscObject)rl2g);CHKERRQ(ierr); 1618f26d0771SStefano Zampini cl2g = rl2g; 1619f26d0771SStefano Zampini } 1620f26d0771SStefano Zampini /* create the MATIS submatrix */ 1621f26d0771SStefano Zampini ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr); 1622f26d0771SStefano Zampini ierr = MatCreate(PetscObjectComm((PetscObject)A),submat);CHKERRQ(ierr); 1623f26d0771SStefano Zampini ierr = MatSetSizes(*submat,PETSC_DECIDE,PETSC_DECIDE,M,N);CHKERRQ(ierr); 1624f26d0771SStefano Zampini ierr = MatSetType(*submat,MATIS);CHKERRQ(ierr); 1625b0aa3428SStefano Zampini matis = (Mat_IS*)((*submat)->data); 1626f26d0771SStefano Zampini matis->islocalref = PETSC_TRUE; 1627f26d0771SStefano Zampini ierr = MatSetLocalToGlobalMapping(*submat,rl2g,cl2g);CHKERRQ(ierr); 1628f26d0771SStefano Zampini ierr = MatISGetLocalMat(A,&lA);CHKERRQ(ierr); 1629f26d0771SStefano Zampini ierr = MatISSetLocalMat(*submat,lA);CHKERRQ(ierr); 1630f26d0771SStefano Zampini ierr = MatSetUp(*submat);CHKERRQ(ierr); 1631f26d0771SStefano Zampini ierr = MatAssemblyBegin(*submat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1632f26d0771SStefano Zampini ierr = MatAssemblyEnd(*submat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1633f26d0771SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&rl2g);CHKERRQ(ierr); 1634f26d0771SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&cl2g);CHKERRQ(ierr); 1635f26d0771SStefano Zampini /* remove unsupported ops */ 1636f26d0771SStefano Zampini ierr = PetscMemzero((*submat)->ops,sizeof(struct _MatOps));CHKERRQ(ierr); 1637f26d0771SStefano Zampini (*submat)->ops->destroy = MatDestroy_IS; 1638f26d0771SStefano Zampini (*submat)->ops->setvalueslocal = MatSetValuesLocal_SubMat_IS; 1639f26d0771SStefano Zampini (*submat)->ops->setvaluesblockedlocal = MatSetValuesBlockedLocal_SubMat_IS; 1640f26d0771SStefano Zampini (*submat)->ops->assemblybegin = MatAssemblyBegin_IS; 1641f26d0771SStefano Zampini (*submat)->ops->assemblyend = MatAssemblyEnd_IS; 1642f26d0771SStefano Zampini PetscFunctionReturn(0); 1643f26d0771SStefano Zampini } 1644f26d0771SStefano Zampini 1645f26d0771SStefano Zampini #undef __FUNCT__ 1646284134d9SBarry Smith #define __FUNCT__ "MatCreateIS" 1647284134d9SBarry Smith /*@ 16483c212e90SHong Zhang MatCreateIS - Creates a "process" unassembled matrix, assembled on each 1649284134d9SBarry Smith process but not across processes. 1650284134d9SBarry Smith 1651284134d9SBarry Smith Input Parameters: 1652284134d9SBarry Smith + comm - MPI communicator that will share the matrix 1653e176bc59SStefano Zampini . bs - block size of the matrix 1654df3898eeSBarry Smith . m,n,M,N - local and/or global sizes of the left and right vector used in matrix vector products 1655e176bc59SStefano Zampini . rmap - local to global map for rows 1656e176bc59SStefano Zampini - cmap - local to global map for cols 1657284134d9SBarry Smith 1658284134d9SBarry Smith Output Parameter: 1659284134d9SBarry Smith . A - the resulting matrix 1660284134d9SBarry Smith 16618e6c10adSSatish Balay Level: advanced 16628e6c10adSSatish Balay 16633c212e90SHong Zhang Notes: See MATIS for more details. 16646fdf41d1SStefano Zampini m and n are NOT related to the size of the map; they represent the size of the local parts of the vectors 16656fdf41d1SStefano Zampini used in MatMult operations. The sizes of rmap and cmap define the size of the local matrices. 16663c212e90SHong Zhang If either rmap or cmap are NULL, then the matrix is assumed to be square. 1667284134d9SBarry Smith 1668284134d9SBarry Smith .seealso: MATIS, MatSetLocalToGlobalMapping() 1669284134d9SBarry Smith @*/ 1670e176bc59SStefano Zampini PetscErrorCode MatCreateIS(MPI_Comm comm,PetscInt bs,PetscInt m,PetscInt n,PetscInt M,PetscInt N,ISLocalToGlobalMapping rmap,ISLocalToGlobalMapping cmap,Mat *A) 1671284134d9SBarry Smith { 1672284134d9SBarry Smith PetscErrorCode ierr; 1673284134d9SBarry Smith 1674284134d9SBarry Smith PetscFunctionBegin; 16756fdf41d1SStefano Zampini if (!rmap && !cmap) SETERRQ(comm,PETSC_ERR_USER,"You need to provide at least one of the mappings"); 1676284134d9SBarry Smith ierr = MatCreate(comm,A);CHKERRQ(ierr); 16776fdf41d1SStefano Zampini if (bs > 0) { 1678d3ee2243SStefano Zampini ierr = MatSetBlockSize(*A,bs);CHKERRQ(ierr); 16796fdf41d1SStefano Zampini } 1680284134d9SBarry Smith ierr = MatSetSizes(*A,m,n,M,N);CHKERRQ(ierr); 1681284134d9SBarry Smith ierr = MatSetType(*A,MATIS);CHKERRQ(ierr); 1682e176bc59SStefano Zampini if (rmap && cmap) { 1683e176bc59SStefano Zampini ierr = MatSetLocalToGlobalMapping(*A,rmap,cmap);CHKERRQ(ierr); 1684e176bc59SStefano Zampini } else if (!rmap) { 1685e176bc59SStefano Zampini ierr = MatSetLocalToGlobalMapping(*A,cmap,cmap);CHKERRQ(ierr); 1686e176bc59SStefano Zampini } else { 1687e176bc59SStefano Zampini ierr = MatSetLocalToGlobalMapping(*A,rmap,rmap);CHKERRQ(ierr); 1688e176bc59SStefano Zampini } 1689284134d9SBarry Smith PetscFunctionReturn(0); 1690284134d9SBarry Smith } 1691284134d9SBarry Smith 1692b4319ba4SBarry Smith /*MC 1693f26d0771SStefano Zampini MATIS - MATIS = "is" - A matrix type to be used for using the non-overlapping domain decomposition methods (e.g. PCBDDC or KSPFETIDP). 1694b4319ba4SBarry Smith This stores the matrices in globally unassembled form. Each processor 1695b4319ba4SBarry Smith assembles only its local Neumann problem and the parallel matrix vector 1696b4319ba4SBarry Smith product is handled "implicitly". 1697b4319ba4SBarry Smith 1698b4319ba4SBarry Smith Operations Provided: 16996726f965SBarry Smith + MatMult() 17002e74eeadSLisandro Dalcin . MatMultAdd() 17012e74eeadSLisandro Dalcin . MatMultTranspose() 17022e74eeadSLisandro Dalcin . MatMultTransposeAdd() 17036726f965SBarry Smith . MatZeroEntries() 17046726f965SBarry Smith . MatSetOption() 17052e74eeadSLisandro Dalcin . MatZeroRows() 17062e74eeadSLisandro Dalcin . MatSetValues() 170797563a80SStefano Zampini . MatSetValuesBlocked() 17086726f965SBarry Smith . MatSetValuesLocal() 170997563a80SStefano Zampini . MatSetValuesBlockedLocal() 17102e74eeadSLisandro Dalcin . MatScale() 17112e74eeadSLisandro Dalcin . MatGetDiagonal() 17122b404112SStefano Zampini . MatMissingDiagonal() 17132b404112SStefano Zampini . MatDuplicate() 17142b404112SStefano Zampini . MatCopy() 1715f26d0771SStefano Zampini . MatAXPY() 1716f26d0771SStefano Zampini . MatGetSubMatrix() 1717f26d0771SStefano Zampini . MatGetLocalSubMatrix() 1718d7f69cd0SStefano Zampini . MatTranspose() 17196726f965SBarry Smith - MatSetLocalToGlobalMapping() 1720b4319ba4SBarry Smith 1721b4319ba4SBarry Smith Options Database Keys: 1722b4319ba4SBarry Smith . -mat_type is - sets the matrix type to "is" during a call to MatSetFromOptions() 1723b4319ba4SBarry Smith 1724b4319ba4SBarry Smith Notes: Options prefix for the inner matrix are given by -is_mat_xxx 1725b4319ba4SBarry Smith 1726b4319ba4SBarry Smith You must call MatSetLocalToGlobalMapping() before using this matrix type. 1727b4319ba4SBarry Smith 1728b4319ba4SBarry Smith You can do matrix preallocation on the local matrix after you obtain it with 1729eb82efa4SStefano Zampini MatISGetLocalMat(); otherwise, you could use MatISSetPreallocation() 1730b4319ba4SBarry Smith 1731b4319ba4SBarry Smith Level: advanced 1732b4319ba4SBarry Smith 1733f26d0771SStefano Zampini .seealso: Mat, MatISGetLocalMat(), MatSetLocalToGlobalMapping(), MatISSetPreallocation(), MatCreateIS(), PCBDDC, KSPFETIDP 1734b4319ba4SBarry Smith 1735b4319ba4SBarry Smith M*/ 1736b4319ba4SBarry Smith 1737b4319ba4SBarry Smith #undef __FUNCT__ 1738b4319ba4SBarry Smith #define __FUNCT__ "MatCreate_IS" 17398cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatCreate_IS(Mat A) 1740b4319ba4SBarry Smith { 1741dfbe8321SBarry Smith PetscErrorCode ierr; 1742b4319ba4SBarry Smith Mat_IS *b; 1743b4319ba4SBarry Smith 1744b4319ba4SBarry Smith PetscFunctionBegin; 1745b00a9115SJed Brown ierr = PetscNewLog(A,&b);CHKERRQ(ierr); 1746b4319ba4SBarry Smith A->data = (void*)b; 1747b4319ba4SBarry Smith 1748e176bc59SStefano Zampini /* matrix ops */ 1749e176bc59SStefano Zampini ierr = PetscMemzero(A->ops,sizeof(struct _MatOps));CHKERRQ(ierr); 1750b4319ba4SBarry Smith A->ops->mult = MatMult_IS; 17512e74eeadSLisandro Dalcin A->ops->multadd = MatMultAdd_IS; 17522e74eeadSLisandro Dalcin A->ops->multtranspose = MatMultTranspose_IS; 17532e74eeadSLisandro Dalcin A->ops->multtransposeadd = MatMultTransposeAdd_IS; 1754b4319ba4SBarry Smith A->ops->destroy = MatDestroy_IS; 1755b4319ba4SBarry Smith A->ops->setlocaltoglobalmapping = MatSetLocalToGlobalMapping_IS; 17562e74eeadSLisandro Dalcin A->ops->setvalues = MatSetValues_IS; 175798921651SStefano Zampini A->ops->setvaluesblocked = MatSetValuesBlocked_IS; 1758b4319ba4SBarry Smith A->ops->setvalueslocal = MatSetValuesLocal_IS; 1759f0006bf2SLisandro Dalcin A->ops->setvaluesblockedlocal = MatSetValuesBlockedLocal_IS; 17602e74eeadSLisandro Dalcin A->ops->zerorows = MatZeroRows_IS; 1761f0ae7da4SStefano Zampini A->ops->zerorowscolumns = MatZeroRowsColumns_IS; 1762b4319ba4SBarry Smith A->ops->assemblybegin = MatAssemblyBegin_IS; 1763b4319ba4SBarry Smith A->ops->assemblyend = MatAssemblyEnd_IS; 1764b4319ba4SBarry Smith A->ops->view = MatView_IS; 17656726f965SBarry Smith A->ops->zeroentries = MatZeroEntries_IS; 17662e74eeadSLisandro Dalcin A->ops->scale = MatScale_IS; 17672e74eeadSLisandro Dalcin A->ops->getdiagonal = MatGetDiagonal_IS; 17686726f965SBarry Smith A->ops->setoption = MatSetOption_IS; 176969796d55SStefano Zampini A->ops->ishermitian = MatIsHermitian_IS; 177069796d55SStefano Zampini A->ops->issymmetric = MatIsSymmetric_IS; 1771ad6194a2SStefano Zampini A->ops->duplicate = MatDuplicate_IS; 17726bd84002SStefano Zampini A->ops->missingdiagonal = MatMissingDiagonal_IS; 17732b404112SStefano Zampini A->ops->copy = MatCopy_IS; 1774659959c5SStefano Zampini A->ops->getlocalsubmatrix = MatGetLocalSubMatrix_IS; 1775a8116848SStefano Zampini A->ops->getsubmatrix = MatGetSubMatrix_IS; 1776f26d0771SStefano Zampini A->ops->axpy = MatAXPY_IS; 17773fd1c9e7SStefano Zampini A->ops->diagonalset = MatDiagonalSet_IS; 17783fd1c9e7SStefano Zampini A->ops->shift = MatShift_IS; 1779d7f69cd0SStefano Zampini A->ops->transpose = MatTranspose_IS; 17807fa8f2d3SStefano Zampini A->ops->getinfo = MatGetInfo_IS; 1781b4319ba4SBarry Smith 1782b7ce53b6SStefano Zampini /* special MATIS functions */ 1783bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatISGetLocalMat_C",MatISGetLocalMat_IS);CHKERRQ(ierr); 1784bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatISSetLocalMat_C",MatISSetLocalMat_IS);CHKERRQ(ierr); 1785b7ce53b6SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatISGetMPIXAIJ_C",MatISGetMPIXAIJ_IS);CHKERRQ(ierr); 17862e1947a5SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatISSetPreallocation_C",MatISSetPreallocation_IS);CHKERRQ(ierr); 178717667f90SBarry Smith ierr = PetscObjectChangeTypeName((PetscObject)A,MATIS);CHKERRQ(ierr); 1788b4319ba4SBarry Smith PetscFunctionReturn(0); 1789b4319ba4SBarry Smith } 1790