1be1d678aSKris Buschelman 2b4319ba4SBarry Smith /* 3b4319ba4SBarry Smith Creates a matrix class for using the Neumann-Neumann type preconditioners. 4b4319ba4SBarry Smith This stores the matrices in globally unassembled form. Each processor 5b4319ba4SBarry Smith assembles only its local Neumann problem and the parallel matrix vector 6b4319ba4SBarry Smith product is handled "implicitly". 7b4319ba4SBarry Smith 8b4319ba4SBarry Smith We provide: 9b4319ba4SBarry Smith MatMult() 10b4319ba4SBarry Smith 11b4319ba4SBarry Smith Currently this allows for only one subdomain per processor. 12b4319ba4SBarry Smith 13b4319ba4SBarry Smith */ 14b4319ba4SBarry Smith 15c6db04a5SJed Brown #include <../src/mat/impls/is/matis.h> /*I "petscmat.h" I*/ 16*4f2d7cafSStefano Zampini #include <petsc/private/sfimpl.h> 1728f4e0baSStefano Zampini 18cf0a3239SStefano Zampini #undef __FUNCT__ 19cf0a3239SStefano Zampini #define __FUNCT__ "MatISSetUpSF" 20cf0a3239SStefano Zampini /*@ 21cf0a3239SStefano Zampini MatISSetUpSF - Setup star forest object used by MatIS during MatISSetPreallocation. 22cf0a3239SStefano Zampini 23cf0a3239SStefano Zampini Collective on MPI_Comm 24cf0a3239SStefano Zampini 25cf0a3239SStefano Zampini Input Parameters: 26cf0a3239SStefano Zampini + A - the matrix 27cf0a3239SStefano Zampini 28cf0a3239SStefano Zampini Level: advanced 29cf0a3239SStefano Zampini 30cf0a3239SStefano Zampini Notes: This function does not be to be called by the user. 31cf0a3239SStefano Zampini 32cf0a3239SStefano Zampini .keywords: matrix 33cf0a3239SStefano Zampini 34cf0a3239SStefano Zampini .seealso: MatCreate(), MatCreateIS(), MatISSetPreallocation(), MatISGetLocalMat() 35cf0a3239SStefano Zampini @*/ 36cf0a3239SStefano Zampini PetscErrorCode MatISSetUpSF(Mat A) 37cf0a3239SStefano Zampini { 38cf0a3239SStefano Zampini PetscErrorCode ierr; 39cf0a3239SStefano Zampini 40cf0a3239SStefano Zampini PetscFunctionBegin; 41cf0a3239SStefano Zampini PetscValidHeaderSpecific(A,MAT_CLASSID,1); 42cf0a3239SStefano Zampini PetscValidType(A,1); 43cf0a3239SStefano Zampini ierr = PetscTryMethod(A,"MatISSetUpSF_C",(Mat),(A));CHKERRQ(ierr); 44cf0a3239SStefano Zampini PetscFunctionReturn(0); 45cf0a3239SStefano Zampini } 46a72627d2SStefano Zampini 4728f4e0baSStefano Zampini #undef __FUNCT__ 48cf0a3239SStefano Zampini #define __FUNCT__ "MatISSetUpSF_IS" 49cf0a3239SStefano Zampini static PetscErrorCode MatISSetUpSF_IS(Mat B) 5028f4e0baSStefano Zampini { 5128f4e0baSStefano Zampini Mat_IS *matis = (Mat_IS*)(B->data); 5228f4e0baSStefano Zampini const PetscInt *gidxs; 53*4f2d7cafSStefano Zampini PetscInt nleaves; 5428f4e0baSStefano Zampini PetscErrorCode ierr; 5528f4e0baSStefano Zampini 5628f4e0baSStefano Zampini PetscFunctionBegin; 57*4f2d7cafSStefano Zampini if (matis->sf) PetscFunctionReturn(0); 5828f4e0baSStefano Zampini ierr = PetscSFCreate(PetscObjectComm((PetscObject)B),&matis->sf);CHKERRQ(ierr); 593bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(B->rmap->mapping,&gidxs);CHKERRQ(ierr); 60*4f2d7cafSStefano Zampini ierr = ISLocalToGlobalMappingGetSize(B->rmap->mapping,&nleaves);CHKERRQ(ierr); 6128f4e0baSStefano Zampini /* PETSC_OWN_POINTER refers to ilocal which is NULL */ 62*4f2d7cafSStefano Zampini ierr = PetscSFSetGraphLayout(matis->sf,B->rmap,nleaves,NULL,PETSC_OWN_POINTER,gidxs);CHKERRQ(ierr); 633bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(B->rmap->mapping,&gidxs);CHKERRQ(ierr); 64*4f2d7cafSStefano Zampini ierr = PetscMalloc2(matis->sf->nroots,&matis->sf_rootdata,matis->sf->nleaves,&matis->sf_leafdata);CHKERRQ(ierr); 6528f4e0baSStefano Zampini PetscFunctionReturn(0); 6628f4e0baSStefano Zampini } 672e1947a5SStefano Zampini 682e1947a5SStefano Zampini #undef __FUNCT__ 692e1947a5SStefano Zampini #define __FUNCT__ "MatISSetPreallocation" 70eb82efa4SStefano Zampini /*@ 71a88811baSStefano Zampini MatISSetPreallocation - Preallocates memory for a MATIS parallel matrix. 72a88811baSStefano Zampini 73a88811baSStefano Zampini Collective on MPI_Comm 74a88811baSStefano Zampini 75a88811baSStefano Zampini Input Parameters: 76a88811baSStefano Zampini + B - the matrix 77a88811baSStefano Zampini . d_nz - number of nonzeros per row in DIAGONAL portion of local submatrix 78a88811baSStefano Zampini (same value is used for all local rows) 79a88811baSStefano Zampini . d_nnz - array containing the number of nonzeros in the various rows of the 80a88811baSStefano Zampini DIAGONAL portion of the local submatrix (possibly different for each row) 81a88811baSStefano Zampini or NULL, if d_nz is used to specify the nonzero structure. 82a88811baSStefano Zampini The size of this array is equal to the number of local rows, i.e 'm'. 83a88811baSStefano Zampini For matrices that will be factored, you must leave room for (and set) 84a88811baSStefano Zampini the diagonal entry even if it is zero. 85a88811baSStefano Zampini . o_nz - number of nonzeros per row in the OFF-DIAGONAL portion of local 86a88811baSStefano Zampini submatrix (same value is used for all local rows). 87a88811baSStefano Zampini - o_nnz - array containing the number of nonzeros in the various rows of the 88a88811baSStefano Zampini OFF-DIAGONAL portion of the local submatrix (possibly different for 89a88811baSStefano Zampini each row) or NULL, if o_nz is used to specify the nonzero 90a88811baSStefano Zampini structure. The size of this array is equal to the number 91a88811baSStefano Zampini of local rows, i.e 'm'. 92a88811baSStefano Zampini 93a88811baSStefano Zampini If the *_nnz parameter is given then the *_nz parameter is ignored 94a88811baSStefano Zampini 95a88811baSStefano Zampini Level: intermediate 96a88811baSStefano Zampini 97a88811baSStefano Zampini Notes: This function has the same interface as the MPIAIJ preallocation routine in order to simplify the transition 98a88811baSStefano Zampini from the asssembled format to the unassembled one. It overestimates the preallocation of MATIS local 99a88811baSStefano Zampini matrices; for exact preallocation, the user should set the preallocation directly on local matrix objects. 100a88811baSStefano Zampini 101a88811baSStefano Zampini .keywords: matrix 102a88811baSStefano Zampini 103a88811baSStefano Zampini .seealso: MatCreate(), MatCreateIS(), MatMPIAIJSetPreallocation(), MatISGetLocalMat() 104a88811baSStefano Zampini @*/ 1052e1947a5SStefano Zampini PetscErrorCode MatISSetPreallocation(Mat B,PetscInt d_nz,const PetscInt d_nnz[],PetscInt o_nz,const PetscInt o_nnz[]) 1062e1947a5SStefano Zampini { 1072e1947a5SStefano Zampini PetscErrorCode ierr; 1082e1947a5SStefano Zampini 1092e1947a5SStefano Zampini PetscFunctionBegin; 1102e1947a5SStefano Zampini PetscValidHeaderSpecific(B,MAT_CLASSID,1); 1112e1947a5SStefano Zampini PetscValidType(B,1); 1122e1947a5SStefano Zampini ierr = PetscTryMethod(B,"MatISSetPreallocation_C",(Mat,PetscInt,const PetscInt[],PetscInt,const PetscInt[]),(B,d_nz,d_nnz,o_nz,o_nnz));CHKERRQ(ierr); 1132e1947a5SStefano Zampini PetscFunctionReturn(0); 1142e1947a5SStefano Zampini } 1152e1947a5SStefano Zampini 1162e1947a5SStefano Zampini #undef __FUNCT__ 1172e1947a5SStefano Zampini #define __FUNCT__ "MatISSetPreallocation_IS" 1182e1947a5SStefano Zampini PetscErrorCode MatISSetPreallocation_IS(Mat B,PetscInt d_nz,const PetscInt d_nnz[],PetscInt o_nz,const PetscInt o_nnz[]) 1192e1947a5SStefano Zampini { 1202e1947a5SStefano Zampini Mat_IS *matis = (Mat_IS*)(B->data); 12128f4e0baSStefano Zampini PetscInt bs,i,nlocalcols; 1222e1947a5SStefano Zampini PetscErrorCode ierr; 1232e1947a5SStefano Zampini 1242e1947a5SStefano Zampini PetscFunctionBegin; 1256c4ed002SBarry Smith if (!matis->A) SETERRQ(PetscObjectComm((PetscObject)B),PETSC_ERR_SUP,"You should first call MatSetLocalToGlobalMapping"); 126cf0a3239SStefano Zampini ierr = MatISSetUpSF(B);CHKERRQ(ierr); 127*4f2d7cafSStefano Zampini 128*4f2d7cafSStefano Zampini if (!d_nnz) for (i=0;i<matis->sf->nroots;i++) matis->sf_rootdata[i] = d_nz; 129*4f2d7cafSStefano Zampini else for (i=0;i<matis->sf->nroots;i++) matis->sf_rootdata[i] = d_nnz[i]; 130*4f2d7cafSStefano Zampini 131*4f2d7cafSStefano Zampini if (!o_nnz) for (i=0;i<matis->sf->nroots;i++) matis->sf_rootdata[i] += o_nz; 132*4f2d7cafSStefano Zampini else for (i=0;i<matis->sf->nroots;i++) matis->sf_rootdata[i] += o_nnz[i]; 133*4f2d7cafSStefano Zampini 13428f4e0baSStefano Zampini ierr = PetscSFBcastBegin(matis->sf,MPIU_INT,matis->sf_rootdata,matis->sf_leafdata);CHKERRQ(ierr); 13528f4e0baSStefano Zampini ierr = MatGetSize(matis->A,NULL,&nlocalcols);CHKERRQ(ierr); 13628f4e0baSStefano Zampini ierr = MatGetBlockSize(matis->A,&bs);CHKERRQ(ierr); 13728f4e0baSStefano Zampini ierr = PetscSFBcastEnd(matis->sf,MPIU_INT,matis->sf_rootdata,matis->sf_leafdata);CHKERRQ(ierr); 138*4f2d7cafSStefano Zampini 139*4f2d7cafSStefano Zampini for (i=0;i<matis->sf->nleaves;i++) matis->sf_leafdata[i] = PetscMin(matis->sf_leafdata[i],nlocalcols); 14028f4e0baSStefano Zampini ierr = MatSeqAIJSetPreallocation(matis->A,0,matis->sf_leafdata);CHKERRQ(ierr); 141*4f2d7cafSStefano Zampini 142*4f2d7cafSStefano Zampini for (i=0;i<matis->sf->nleaves/bs;i++) matis->sf_leafdata[i] = matis->sf_leafdata[i*bs]/bs; 14328f4e0baSStefano Zampini ierr = MatSeqBAIJSetPreallocation(matis->A,bs,0,matis->sf_leafdata);CHKERRQ(ierr); 144*4f2d7cafSStefano Zampini 145*4f2d7cafSStefano Zampini for (i=0;i<matis->sf->nleaves/bs;i++) matis->sf_leafdata[i] = matis->sf_leafdata[i]-i; 14628f4e0baSStefano Zampini ierr = MatSeqSBAIJSetPreallocation(matis->A,bs,0,matis->sf_leafdata);CHKERRQ(ierr); 1472e1947a5SStefano Zampini PetscFunctionReturn(0); 1482e1947a5SStefano Zampini } 149b4319ba4SBarry Smith 150b4319ba4SBarry Smith #undef __FUNCT__ 1513927de2eSStefano Zampini #define __FUNCT__ "MatISSetMPIXAIJPreallocation_Private" 1523927de2eSStefano Zampini PETSC_EXTERN PetscErrorCode MatISSetMPIXAIJPreallocation_Private(Mat A, Mat B, PetscBool maxreduce) 1533927de2eSStefano Zampini { 1543927de2eSStefano Zampini Mat_IS *matis = (Mat_IS*)(A->data); 1553927de2eSStefano Zampini PetscInt *my_dnz,*my_onz,*dnz,*onz,*mat_ranges,*row_ownership; 156ecf5a873SStefano Zampini const PetscInt *global_indices_r,*global_indices_c; 1573927de2eSStefano Zampini PetscInt i,j,bs,rows,cols; 1583927de2eSStefano Zampini PetscInt lrows,lcols; 1593927de2eSStefano Zampini PetscInt local_rows,local_cols; 1603927de2eSStefano Zampini PetscMPIInt nsubdomains; 1613927de2eSStefano Zampini PetscBool isdense,issbaij; 1623927de2eSStefano Zampini PetscErrorCode ierr; 1633927de2eSStefano Zampini 1643927de2eSStefano Zampini PetscFunctionBegin; 1653927de2eSStefano Zampini ierr = MPI_Comm_size(PetscObjectComm((PetscObject)A),&nsubdomains);CHKERRQ(ierr); 1663927de2eSStefano Zampini ierr = MatGetSize(A,&rows,&cols);CHKERRQ(ierr); 1673927de2eSStefano Zampini ierr = MatGetBlockSize(A,&bs);CHKERRQ(ierr); 1683927de2eSStefano Zampini ierr = MatGetSize(matis->A,&local_rows,&local_cols);CHKERRQ(ierr); 1693927de2eSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)matis->A,MATSEQDENSE,&isdense);CHKERRQ(ierr); 1703927de2eSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)matis->A,MATSEQSBAIJ,&issbaij);CHKERRQ(ierr); 171ecf5a873SStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(A->rmap->mapping,&global_indices_r);CHKERRQ(ierr); 172ecf5a873SStefano Zampini if (A->rmap->mapping != A->cmap->mapping) { 173ecf5a873SStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(A->rmap->mapping,&global_indices_c);CHKERRQ(ierr); 174ecf5a873SStefano Zampini } else { 175ecf5a873SStefano Zampini global_indices_c = global_indices_r; 176ecf5a873SStefano Zampini } 177ecf5a873SStefano Zampini 1783927de2eSStefano Zampini if (issbaij) { 1793927de2eSStefano Zampini ierr = MatGetRowUpperTriangular(matis->A);CHKERRQ(ierr); 1803927de2eSStefano Zampini } 1813927de2eSStefano Zampini /* 182ecf5a873SStefano Zampini An SF reduce is needed to sum up properly on shared rows. 1833927de2eSStefano Zampini Note that generally preallocation is not exact, since it overestimates nonzeros 1843927de2eSStefano Zampini */ 185cf0a3239SStefano Zampini ierr = MatISSetUpSF(A);CHKERRQ(ierr); 1863927de2eSStefano Zampini ierr = MatGetLocalSize(A,&lrows,&lcols);CHKERRQ(ierr); 1873927de2eSStefano Zampini ierr = MatPreallocateInitialize(PetscObjectComm((PetscObject)A),lrows,lcols,dnz,onz);CHKERRQ(ierr); 1883927de2eSStefano Zampini /* All processes need to compute entire row ownership */ 1893927de2eSStefano Zampini ierr = PetscMalloc1(rows,&row_ownership);CHKERRQ(ierr); 1903927de2eSStefano Zampini ierr = MatGetOwnershipRanges(A,(const PetscInt**)&mat_ranges);CHKERRQ(ierr); 1913927de2eSStefano Zampini for (i=0;i<nsubdomains;i++) { 1923927de2eSStefano Zampini for (j=mat_ranges[i];j<mat_ranges[i+1];j++) { 1933927de2eSStefano Zampini row_ownership[j] = i; 1943927de2eSStefano Zampini } 1953927de2eSStefano Zampini } 1963927de2eSStefano Zampini 1973927de2eSStefano Zampini /* 1983927de2eSStefano Zampini my_dnz and my_onz contains exact contribution to preallocation from each local mat 1993927de2eSStefano Zampini then, they will be summed up properly. This way, preallocation is always sufficient 2003927de2eSStefano Zampini */ 2013927de2eSStefano Zampini ierr = PetscCalloc2(local_rows,&my_dnz,local_rows,&my_onz);CHKERRQ(ierr); 2023927de2eSStefano Zampini /* preallocation as a MATAIJ */ 2033927de2eSStefano Zampini if (isdense) { /* special case for dense local matrices */ 2043927de2eSStefano Zampini for (i=0;i<local_rows;i++) { 205ecf5a873SStefano Zampini PetscInt index_row = global_indices_r[i]; 2063927de2eSStefano Zampini for (j=i;j<local_rows;j++) { 2073927de2eSStefano Zampini PetscInt owner = row_ownership[index_row]; 208ecf5a873SStefano Zampini PetscInt index_col = global_indices_c[j]; 2093927de2eSStefano Zampini if (index_col > mat_ranges[owner]-1 && index_col < mat_ranges[owner+1] ) { /* diag block */ 2103927de2eSStefano Zampini my_dnz[i] += 1; 2113927de2eSStefano Zampini } else { /* offdiag block */ 2123927de2eSStefano Zampini my_onz[i] += 1; 2133927de2eSStefano Zampini } 2143927de2eSStefano Zampini /* same as before, interchanging rows and cols */ 2153927de2eSStefano Zampini if (i != j) { 2163927de2eSStefano Zampini owner = row_ownership[index_col]; 2173927de2eSStefano Zampini if (index_row > mat_ranges[owner]-1 && index_row < mat_ranges[owner+1] ) { 2183927de2eSStefano Zampini my_dnz[j] += 1; 2193927de2eSStefano Zampini } else { 2203927de2eSStefano Zampini my_onz[j] += 1; 2213927de2eSStefano Zampini } 2223927de2eSStefano Zampini } 2233927de2eSStefano Zampini } 2243927de2eSStefano Zampini } 225ecf5a873SStefano Zampini } else { /* TODO: this could be optimized using MatGetRowIJ */ 2263927de2eSStefano Zampini for (i=0;i<local_rows;i++) { 2273927de2eSStefano Zampini const PetscInt *cols; 228ecf5a873SStefano Zampini PetscInt ncols,index_row = global_indices_r[i]; 2293927de2eSStefano Zampini ierr = MatGetRow(matis->A,i,&ncols,&cols,NULL);CHKERRQ(ierr); 2303927de2eSStefano Zampini for (j=0;j<ncols;j++) { 2313927de2eSStefano Zampini PetscInt owner = row_ownership[index_row]; 232ecf5a873SStefano Zampini PetscInt index_col = global_indices_c[cols[j]]; 2333927de2eSStefano Zampini if (index_col > mat_ranges[owner]-1 && index_col < mat_ranges[owner+1] ) { /* diag block */ 2343927de2eSStefano Zampini my_dnz[i] += 1; 2353927de2eSStefano Zampini } else { /* offdiag block */ 2363927de2eSStefano Zampini my_onz[i] += 1; 2373927de2eSStefano Zampini } 2383927de2eSStefano Zampini /* same as before, interchanging rows and cols */ 239d9a9e74cSStefano Zampini if (issbaij && index_col != index_row) { 2403927de2eSStefano Zampini owner = row_ownership[index_col]; 2413927de2eSStefano Zampini if (index_row > mat_ranges[owner]-1 && index_row < mat_ranges[owner+1] ) { 242d9a9e74cSStefano Zampini my_dnz[cols[j]] += 1; 2433927de2eSStefano Zampini } else { 244d9a9e74cSStefano Zampini my_onz[cols[j]] += 1; 2453927de2eSStefano Zampini } 2463927de2eSStefano Zampini } 2473927de2eSStefano Zampini } 2483927de2eSStefano Zampini ierr = MatRestoreRow(matis->A,i,&ncols,&cols,NULL);CHKERRQ(ierr); 2493927de2eSStefano Zampini } 2503927de2eSStefano Zampini } 251ecf5a873SStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(A->rmap->mapping,&global_indices_r);CHKERRQ(ierr); 252ecf5a873SStefano Zampini if (global_indices_c != global_indices_r) { 253ecf5a873SStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(A->rmap->mapping,&global_indices_c);CHKERRQ(ierr); 254ecf5a873SStefano Zampini } 2553927de2eSStefano Zampini ierr = PetscFree(row_ownership);CHKERRQ(ierr); 256ecf5a873SStefano Zampini 257ecf5a873SStefano Zampini /* Reduce my_dnz and my_onz */ 2583927de2eSStefano Zampini if (maxreduce) { 2593927de2eSStefano Zampini ierr = PetscSFReduceBegin(matis->sf,MPIU_INT,my_dnz,dnz,MPI_MAX);CHKERRQ(ierr); 2603927de2eSStefano Zampini ierr = PetscSFReduceEnd(matis->sf,MPIU_INT,my_dnz,dnz,MPI_MAX);CHKERRQ(ierr); 2613927de2eSStefano Zampini ierr = PetscSFReduceBegin(matis->sf,MPIU_INT,my_onz,onz,MPI_MAX);CHKERRQ(ierr); 2623927de2eSStefano Zampini ierr = PetscSFReduceEnd(matis->sf,MPIU_INT,my_onz,onz,MPI_MAX);CHKERRQ(ierr); 2633927de2eSStefano Zampini } else { 2643927de2eSStefano Zampini ierr = PetscSFReduceBegin(matis->sf,MPIU_INT,my_dnz,dnz,MPI_SUM);CHKERRQ(ierr); 2653927de2eSStefano Zampini ierr = PetscSFReduceEnd(matis->sf,MPIU_INT,my_dnz,dnz,MPI_SUM);CHKERRQ(ierr); 2663927de2eSStefano Zampini ierr = PetscSFReduceBegin(matis->sf,MPIU_INT,my_onz,onz,MPI_SUM);CHKERRQ(ierr); 2673927de2eSStefano Zampini ierr = PetscSFReduceEnd(matis->sf,MPIU_INT,my_onz,onz,MPI_SUM);CHKERRQ(ierr); 2683927de2eSStefano Zampini } 2693927de2eSStefano Zampini ierr = PetscFree2(my_dnz,my_onz);CHKERRQ(ierr); 2703927de2eSStefano Zampini 2713927de2eSStefano Zampini /* Resize preallocation if overestimated */ 2723927de2eSStefano Zampini for (i=0;i<lrows;i++) { 2733927de2eSStefano Zampini dnz[i] = PetscMin(dnz[i],lcols); 2743927de2eSStefano Zampini onz[i] = PetscMin(onz[i],cols-lcols); 2753927de2eSStefano Zampini } 2763927de2eSStefano Zampini /* set preallocation */ 2773927de2eSStefano Zampini ierr = MatMPIAIJSetPreallocation(B,0,dnz,0,onz);CHKERRQ(ierr); 2783927de2eSStefano Zampini for (i=0;i<lrows/bs;i++) { 2793927de2eSStefano Zampini dnz[i] = dnz[i*bs]/bs; 2803927de2eSStefano Zampini onz[i] = onz[i*bs]/bs; 2813927de2eSStefano Zampini } 2823927de2eSStefano Zampini ierr = MatMPIBAIJSetPreallocation(B,bs,0,dnz,0,onz);CHKERRQ(ierr); 2833927de2eSStefano Zampini ierr = MatMPISBAIJSetPreallocation(B,bs,0,dnz,0,onz);CHKERRQ(ierr); 2843927de2eSStefano Zampini ierr = MatPreallocateFinalize(dnz,onz);CHKERRQ(ierr); 2853927de2eSStefano Zampini if (issbaij) { 2863927de2eSStefano Zampini ierr = MatRestoreRowUpperTriangular(matis->A);CHKERRQ(ierr); 2873927de2eSStefano Zampini } 2883927de2eSStefano Zampini PetscFunctionReturn(0); 2893927de2eSStefano Zampini } 2903927de2eSStefano Zampini 2913927de2eSStefano Zampini #undef __FUNCT__ 292b7ce53b6SStefano Zampini #define __FUNCT__ "MatISGetMPIXAIJ_IS" 293b7ce53b6SStefano Zampini PetscErrorCode MatISGetMPIXAIJ_IS(Mat mat, MatReuse reuse, Mat *M) 294b7ce53b6SStefano Zampini { 295b7ce53b6SStefano Zampini Mat_IS *matis = (Mat_IS*)(mat->data); 296d9a9e74cSStefano Zampini Mat local_mat; 297b7ce53b6SStefano Zampini /* info on mat */ 2983cfa4ea4SStefano Zampini PetscInt bs,rows,cols,lrows,lcols; 299b7ce53b6SStefano Zampini PetscInt local_rows,local_cols; 300686e3a49SStefano Zampini PetscBool isdense,issbaij,isseqaij; 3017c03b4e8SStefano Zampini PetscMPIInt nsubdomains; 302b7ce53b6SStefano Zampini /* values insertion */ 303b7ce53b6SStefano Zampini PetscScalar *array; 304b7ce53b6SStefano Zampini /* work */ 305b7ce53b6SStefano Zampini PetscErrorCode ierr; 306b7ce53b6SStefano Zampini 307b7ce53b6SStefano Zampini PetscFunctionBegin; 308b7ce53b6SStefano Zampini /* get info from mat */ 3097c03b4e8SStefano Zampini ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&nsubdomains);CHKERRQ(ierr); 3107c03b4e8SStefano Zampini if (nsubdomains == 1) { 3117c03b4e8SStefano Zampini if (reuse == MAT_INITIAL_MATRIX) { 3127c03b4e8SStefano Zampini ierr = MatDuplicate(matis->A,MAT_COPY_VALUES,&(*M));CHKERRQ(ierr); 3137c03b4e8SStefano Zampini } else { 3147c03b4e8SStefano Zampini ierr = MatCopy(matis->A,*M,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 3157c03b4e8SStefano Zampini } 3167c03b4e8SStefano Zampini PetscFunctionReturn(0); 3177c03b4e8SStefano Zampini } 318b7ce53b6SStefano Zampini ierr = MatGetSize(mat,&rows,&cols);CHKERRQ(ierr); 319b7ce53b6SStefano Zampini ierr = MatGetBlockSize(mat,&bs);CHKERRQ(ierr); 3203cfa4ea4SStefano Zampini ierr = MatGetLocalSize(mat,&lrows,&lcols);CHKERRQ(ierr); 321b7ce53b6SStefano Zampini ierr = MatGetSize(matis->A,&local_rows,&local_cols);CHKERRQ(ierr); 322b7ce53b6SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)matis->A,MATSEQDENSE,&isdense);CHKERRQ(ierr); 323686e3a49SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)matis->A,MATSEQAIJ,&isseqaij);CHKERRQ(ierr); 324b7ce53b6SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)matis->A,MATSEQSBAIJ,&issbaij);CHKERRQ(ierr); 325b7ce53b6SStefano Zampini 326b7ce53b6SStefano Zampini if (reuse == MAT_INITIAL_MATRIX) { 327b7ce53b6SStefano Zampini MatType new_mat_type; 3283927de2eSStefano Zampini PetscBool issbaij_red; 329b7ce53b6SStefano Zampini 330b7ce53b6SStefano Zampini /* determining new matrix type */ 331b2566f29SBarry Smith ierr = MPIU_Allreduce(&issbaij,&issbaij_red,1,MPIU_BOOL,MPI_LAND,PetscObjectComm((PetscObject)mat));CHKERRQ(ierr); 332b7ce53b6SStefano Zampini if (issbaij_red) { 333b7ce53b6SStefano Zampini new_mat_type = MATSBAIJ; 334b7ce53b6SStefano Zampini } else { 335b7ce53b6SStefano Zampini if (bs>1) { 336b7ce53b6SStefano Zampini new_mat_type = MATBAIJ; 337b7ce53b6SStefano Zampini } else { 338b7ce53b6SStefano Zampini new_mat_type = MATAIJ; 339b7ce53b6SStefano Zampini } 340b7ce53b6SStefano Zampini } 341b7ce53b6SStefano Zampini 3423927de2eSStefano Zampini ierr = MatCreate(PetscObjectComm((PetscObject)mat),M);CHKERRQ(ierr); 3433cfa4ea4SStefano Zampini ierr = MatSetSizes(*M,lrows,lcols,rows,cols);CHKERRQ(ierr); 3443927de2eSStefano Zampini ierr = MatSetBlockSize(*M,bs);CHKERRQ(ierr); 3453927de2eSStefano Zampini ierr = MatSetType(*M,new_mat_type);CHKERRQ(ierr); 3463927de2eSStefano Zampini ierr = MatISSetMPIXAIJPreallocation_Private(mat,*M,PETSC_FALSE);CHKERRQ(ierr); 347b7ce53b6SStefano Zampini } else { 3483cfa4ea4SStefano Zampini PetscInt mbs,mrows,mcols,mlrows,mlcols; 349b7ce53b6SStefano Zampini /* some checks */ 350b7ce53b6SStefano Zampini ierr = MatGetBlockSize(*M,&mbs);CHKERRQ(ierr); 351b7ce53b6SStefano Zampini ierr = MatGetSize(*M,&mrows,&mcols);CHKERRQ(ierr); 3523cfa4ea4SStefano Zampini ierr = MatGetLocalSize(*M,&mlrows,&mlcols);CHKERRQ(ierr); 3536c4ed002SBarry Smith if (mrows != rows) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot reuse matrix. Wrong number of rows (%d != %d)",rows,mrows); 3546c4ed002SBarry Smith if (mcols != cols) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot reuse matrix. Wrong number of cols (%d != %d)",cols,mcols); 3556c4ed002SBarry Smith if (mlrows != lrows) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot reuse matrix. Wrong number of local rows (%d != %d)",lrows,mlrows); 3566c4ed002SBarry Smith if (mlcols != lcols) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot reuse matrix. Wrong number of local cols (%d != %d)",lcols,mlcols); 3576c4ed002SBarry Smith if (mbs != bs) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot reuse matrix. Wrong block size (%d != %d)",bs,mbs); 358b7ce53b6SStefano Zampini ierr = MatZeroEntries(*M);CHKERRQ(ierr); 359b7ce53b6SStefano Zampini } 360d9a9e74cSStefano Zampini 361d9a9e74cSStefano Zampini if (issbaij) { 362d9a9e74cSStefano Zampini ierr = MatConvert(matis->A,MATSEQBAIJ,MAT_INITIAL_MATRIX,&local_mat);CHKERRQ(ierr); 363d9a9e74cSStefano Zampini } else { 364d9a9e74cSStefano Zampini ierr = PetscObjectReference((PetscObject)matis->A);CHKERRQ(ierr); 365d9a9e74cSStefano Zampini local_mat = matis->A; 366d9a9e74cSStefano Zampini } 367686e3a49SStefano Zampini 368b7ce53b6SStefano Zampini /* Set values */ 369ecf5a873SStefano Zampini ierr = MatSetLocalToGlobalMapping(*M,mat->rmap->mapping,mat->cmap->mapping);CHKERRQ(ierr); 370b7ce53b6SStefano Zampini if (isdense) { /* special case for dense local matrices */ 371ecf5a873SStefano Zampini PetscInt i,*dummy_rows,*dummy_cols; 372ecf5a873SStefano Zampini 373ecf5a873SStefano Zampini if (local_rows != local_cols) { 374ecf5a873SStefano Zampini ierr = PetscMalloc2(local_rows,&dummy_rows,local_cols,&dummy_cols);CHKERRQ(ierr); 375ecf5a873SStefano Zampini for (i=0;i<local_rows;i++) dummy_rows[i] = i; 376ecf5a873SStefano Zampini for (i=0;i<local_cols;i++) dummy_cols[i] = i; 377ecf5a873SStefano Zampini } else { 378ecf5a873SStefano Zampini ierr = PetscMalloc1(local_rows,&dummy_rows);CHKERRQ(ierr); 379ecf5a873SStefano Zampini for (i=0;i<local_rows;i++) dummy_rows[i] = i; 380ecf5a873SStefano Zampini dummy_cols = dummy_rows; 381ecf5a873SStefano Zampini } 382b7ce53b6SStefano Zampini ierr = MatSetOption(*M,MAT_ROW_ORIENTED,PETSC_FALSE);CHKERRQ(ierr); 383d9a9e74cSStefano Zampini ierr = MatDenseGetArray(local_mat,&array);CHKERRQ(ierr); 384ecf5a873SStefano Zampini ierr = MatSetValuesLocal(*M,local_rows,dummy_rows,local_cols,dummy_cols,array,ADD_VALUES);CHKERRQ(ierr); 385d9a9e74cSStefano Zampini ierr = MatDenseRestoreArray(local_mat,&array);CHKERRQ(ierr); 386ecf5a873SStefano Zampini if (dummy_rows != dummy_cols) { 387ecf5a873SStefano Zampini ierr = PetscFree2(dummy_rows,dummy_cols);CHKERRQ(ierr); 388ecf5a873SStefano Zampini } else { 389ecf5a873SStefano Zampini ierr = PetscFree(dummy_rows);CHKERRQ(ierr); 390ecf5a873SStefano Zampini } 391686e3a49SStefano Zampini } else if (isseqaij) { 392ecf5a873SStefano Zampini PetscInt i,nvtxs,*xadj,*adjncy; 393686e3a49SStefano Zampini PetscBool done; 394686e3a49SStefano Zampini 395d9a9e74cSStefano Zampini ierr = MatGetRowIJ(local_mat,0,PETSC_FALSE,PETSC_FALSE,&nvtxs,(const PetscInt**)&xadj,(const PetscInt**)&adjncy,&done);CHKERRQ(ierr); 3966c4ed002SBarry Smith if (!done) SETERRQ1(PetscObjectComm((PetscObject)local_mat),PETSC_ERR_PLIB,"Error in MatRestoreRowIJ called in %s\n",__FUNCT__); 397d9a9e74cSStefano Zampini ierr = MatSeqAIJGetArray(local_mat,&array);CHKERRQ(ierr); 398686e3a49SStefano Zampini for (i=0;i<nvtxs;i++) { 399ecf5a873SStefano Zampini ierr = MatSetValuesLocal(*M,1,&i,xadj[i+1]-xadj[i],adjncy+xadj[i],array+xadj[i],ADD_VALUES);CHKERRQ(ierr); 400686e3a49SStefano Zampini } 401d9a9e74cSStefano Zampini ierr = MatRestoreRowIJ(local_mat,0,PETSC_FALSE,PETSC_FALSE,&nvtxs,(const PetscInt**)&xadj,(const PetscInt**)&adjncy,&done);CHKERRQ(ierr); 4026c4ed002SBarry Smith if (!done) SETERRQ1(PetscObjectComm((PetscObject)local_mat),PETSC_ERR_PLIB,"Error in MatRestoreRowIJ called in %s\n",__FUNCT__); 403d9a9e74cSStefano Zampini ierr = MatSeqAIJRestoreArray(local_mat,&array);CHKERRQ(ierr); 404686e3a49SStefano Zampini } else { /* very basic values insertion for all other matrix types */ 405ecf5a873SStefano Zampini PetscInt i; 406c0962df8SStefano Zampini 407686e3a49SStefano Zampini for (i=0;i<local_rows;i++) { 408686e3a49SStefano Zampini PetscInt j; 409ecf5a873SStefano Zampini const PetscInt *local_indices_cols; 410686e3a49SStefano Zampini 411ecf5a873SStefano Zampini ierr = MatGetRow(local_mat,i,&j,&local_indices_cols,(const PetscScalar**)&array);CHKERRQ(ierr); 412ecf5a873SStefano Zampini ierr = MatSetValuesLocal(*M,1,&i,j,local_indices_cols,array,ADD_VALUES);CHKERRQ(ierr); 413ecf5a873SStefano Zampini ierr = MatRestoreRow(local_mat,i,&j,&local_indices_cols,(const PetscScalar**)&array);CHKERRQ(ierr); 414686e3a49SStefano Zampini } 415b7ce53b6SStefano Zampini } 416b7ce53b6SStefano Zampini ierr = MatAssemblyBegin(*M,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 417d9a9e74cSStefano Zampini ierr = MatDestroy(&local_mat);CHKERRQ(ierr); 418b7ce53b6SStefano Zampini ierr = MatAssemblyEnd(*M,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 419b7ce53b6SStefano Zampini if (isdense) { 420b7ce53b6SStefano Zampini ierr = MatSetOption(*M,MAT_ROW_ORIENTED,PETSC_TRUE);CHKERRQ(ierr); 421b7ce53b6SStefano Zampini } 422b7ce53b6SStefano Zampini PetscFunctionReturn(0); 423b7ce53b6SStefano Zampini } 424b7ce53b6SStefano Zampini 425b7ce53b6SStefano Zampini #undef __FUNCT__ 426b7ce53b6SStefano Zampini #define __FUNCT__ "MatISGetMPIXAIJ" 427b7ce53b6SStefano Zampini /*@ 428b7ce53b6SStefano Zampini MatISGetMPIXAIJ - Converts MATIS matrix into a parallel AIJ format 429b7ce53b6SStefano Zampini 430b7ce53b6SStefano Zampini Input Parameter: 431b7ce53b6SStefano Zampini . mat - the matrix (should be of type MATIS) 432b7ce53b6SStefano Zampini . reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 433b7ce53b6SStefano Zampini 434b7ce53b6SStefano Zampini Output Parameter: 435b7ce53b6SStefano Zampini . newmat - the matrix in AIJ format 436b7ce53b6SStefano Zampini 437b7ce53b6SStefano Zampini Level: developer 438b7ce53b6SStefano Zampini 439eb82efa4SStefano Zampini Notes: mat and *newmat cannot be the same object when MAT_REUSE_MATRIX is requested. 440b7ce53b6SStefano Zampini 441b7ce53b6SStefano Zampini .seealso: MATIS 442b7ce53b6SStefano Zampini @*/ 443b7ce53b6SStefano Zampini PetscErrorCode MatISGetMPIXAIJ(Mat mat, MatReuse reuse, Mat *newmat) 444b7ce53b6SStefano Zampini { 445b7ce53b6SStefano Zampini PetscErrorCode ierr; 446b7ce53b6SStefano Zampini 447b7ce53b6SStefano Zampini PetscFunctionBegin; 448b7ce53b6SStefano Zampini PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 449b7ce53b6SStefano Zampini PetscValidLogicalCollectiveEnum(mat,reuse,2); 450b7ce53b6SStefano Zampini PetscValidPointer(newmat,3); 451b7ce53b6SStefano Zampini if (reuse != MAT_INITIAL_MATRIX) { 452b7ce53b6SStefano Zampini PetscValidHeaderSpecific(*newmat,MAT_CLASSID,3); 453b7ce53b6SStefano Zampini PetscCheckSameComm(mat,1,*newmat,3); 4546c4ed002SBarry Smith if (mat == *newmat) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot reuse the same matrix"); 455b7ce53b6SStefano Zampini } 456b7ce53b6SStefano Zampini ierr = PetscUseMethod(mat,"MatISGetMPIXAIJ_C",(Mat,MatReuse,Mat*),(mat,reuse,newmat));CHKERRQ(ierr); 457b7ce53b6SStefano Zampini PetscFunctionReturn(0); 458b7ce53b6SStefano Zampini } 459b7ce53b6SStefano Zampini 460b7ce53b6SStefano Zampini #undef __FUNCT__ 461ad6194a2SStefano Zampini #define __FUNCT__ "MatDuplicate_IS" 462ad6194a2SStefano Zampini PetscErrorCode MatDuplicate_IS(Mat mat,MatDuplicateOption op,Mat *newmat) 463ad6194a2SStefano Zampini { 464ad6194a2SStefano Zampini PetscErrorCode ierr; 465ad6194a2SStefano Zampini Mat_IS *matis = (Mat_IS*)(mat->data); 466ad6194a2SStefano Zampini PetscInt bs,m,n,M,N; 467ad6194a2SStefano Zampini Mat B,localmat; 468ad6194a2SStefano Zampini 469ad6194a2SStefano Zampini PetscFunctionBegin; 470ad6194a2SStefano Zampini ierr = MatGetBlockSize(mat,&bs);CHKERRQ(ierr); 471ad6194a2SStefano Zampini ierr = MatGetSize(mat,&M,&N);CHKERRQ(ierr); 472ad6194a2SStefano Zampini ierr = MatGetLocalSize(mat,&m,&n);CHKERRQ(ierr); 473e176bc59SStefano Zampini ierr = MatCreateIS(PetscObjectComm((PetscObject)mat),bs,m,n,M,N,mat->rmap->mapping,mat->cmap->mapping,&B);CHKERRQ(ierr); 474ad6194a2SStefano Zampini ierr = MatDuplicate(matis->A,op,&localmat);CHKERRQ(ierr); 475ad6194a2SStefano Zampini ierr = MatISSetLocalMat(B,localmat);CHKERRQ(ierr); 476b3317aa8SStefano Zampini ierr = MatDestroy(&localmat);CHKERRQ(ierr); 477ad6194a2SStefano Zampini ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 478ad6194a2SStefano Zampini ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 479ad6194a2SStefano Zampini *newmat = B; 480ad6194a2SStefano Zampini PetscFunctionReturn(0); 481ad6194a2SStefano Zampini } 482ad6194a2SStefano Zampini 483ad6194a2SStefano Zampini #undef __FUNCT__ 48469796d55SStefano Zampini #define __FUNCT__ "MatIsHermitian_IS" 48569796d55SStefano Zampini PetscErrorCode MatIsHermitian_IS(Mat A,PetscReal tol,PetscBool *flg) 48669796d55SStefano Zampini { 48769796d55SStefano Zampini PetscErrorCode ierr; 48869796d55SStefano Zampini Mat_IS *matis = (Mat_IS*)A->data; 48969796d55SStefano Zampini PetscBool local_sym; 49069796d55SStefano Zampini 49169796d55SStefano Zampini PetscFunctionBegin; 49269796d55SStefano Zampini ierr = MatIsHermitian(matis->A,tol,&local_sym);CHKERRQ(ierr); 493b2566f29SBarry Smith ierr = MPIU_Allreduce(&local_sym,flg,1,MPIU_BOOL,MPI_LAND,PetscObjectComm((PetscObject)A));CHKERRQ(ierr); 49469796d55SStefano Zampini PetscFunctionReturn(0); 49569796d55SStefano Zampini } 49669796d55SStefano Zampini 49769796d55SStefano Zampini #undef __FUNCT__ 49869796d55SStefano Zampini #define __FUNCT__ "MatIsSymmetric_IS" 49969796d55SStefano Zampini PetscErrorCode MatIsSymmetric_IS(Mat A,PetscReal tol,PetscBool *flg) 50069796d55SStefano Zampini { 50169796d55SStefano Zampini PetscErrorCode ierr; 50269796d55SStefano Zampini Mat_IS *matis = (Mat_IS*)A->data; 50369796d55SStefano Zampini PetscBool local_sym; 50469796d55SStefano Zampini 50569796d55SStefano Zampini PetscFunctionBegin; 50669796d55SStefano Zampini ierr = MatIsSymmetric(matis->A,tol,&local_sym);CHKERRQ(ierr); 507b2566f29SBarry Smith ierr = MPIU_Allreduce(&local_sym,flg,1,MPIU_BOOL,MPI_LAND,PetscObjectComm((PetscObject)A));CHKERRQ(ierr); 50869796d55SStefano Zampini PetscFunctionReturn(0); 50969796d55SStefano Zampini } 51069796d55SStefano Zampini 51169796d55SStefano Zampini #undef __FUNCT__ 512b4319ba4SBarry Smith #define __FUNCT__ "MatDestroy_IS" 513dfbe8321SBarry Smith PetscErrorCode MatDestroy_IS(Mat A) 514b4319ba4SBarry Smith { 515dfbe8321SBarry Smith PetscErrorCode ierr; 516b4319ba4SBarry Smith Mat_IS *b = (Mat_IS*)A->data; 517b4319ba4SBarry Smith 518b4319ba4SBarry Smith PetscFunctionBegin; 5196bf464f9SBarry Smith ierr = MatDestroy(&b->A);CHKERRQ(ierr); 520e176bc59SStefano Zampini ierr = VecScatterDestroy(&b->cctx);CHKERRQ(ierr); 521e176bc59SStefano Zampini ierr = VecScatterDestroy(&b->rctx);CHKERRQ(ierr); 5226bf464f9SBarry Smith ierr = VecDestroy(&b->x);CHKERRQ(ierr); 5236bf464f9SBarry Smith ierr = VecDestroy(&b->y);CHKERRQ(ierr); 52428f4e0baSStefano Zampini ierr = PetscSFDestroy(&b->sf);CHKERRQ(ierr); 52528f4e0baSStefano Zampini ierr = PetscFree2(b->sf_rootdata,b->sf_leafdata);CHKERRQ(ierr); 526bf0cc555SLisandro Dalcin ierr = PetscFree(A->data);CHKERRQ(ierr); 527dbd8c25aSHong Zhang ierr = PetscObjectChangeTypeName((PetscObject)A,0);CHKERRQ(ierr); 528bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatISGetLocalMat_C",NULL);CHKERRQ(ierr); 529b7ce53b6SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatISSetLocalMat_C",NULL);CHKERRQ(ierr); 530b7ce53b6SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatISGetMPIXAIJ_C",NULL);CHKERRQ(ierr); 5312e1947a5SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatISSetPreallocation_C",NULL);CHKERRQ(ierr); 532cf0a3239SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatISSetUpSF_C",NULL);CHKERRQ(ierr); 533b4319ba4SBarry Smith PetscFunctionReturn(0); 534b4319ba4SBarry Smith } 535b4319ba4SBarry Smith 536b4319ba4SBarry Smith #undef __FUNCT__ 537b4319ba4SBarry Smith #define __FUNCT__ "MatMult_IS" 538dfbe8321SBarry Smith PetscErrorCode MatMult_IS(Mat A,Vec x,Vec y) 539b4319ba4SBarry Smith { 540dfbe8321SBarry Smith PetscErrorCode ierr; 541b4319ba4SBarry Smith Mat_IS *is = (Mat_IS*)A->data; 542b4319ba4SBarry Smith PetscScalar zero = 0.0; 543b4319ba4SBarry Smith 544b4319ba4SBarry Smith PetscFunctionBegin; 545b4319ba4SBarry Smith /* scatter the global vector x into the local work vector */ 546e176bc59SStefano Zampini ierr = VecScatterBegin(is->cctx,x,is->x,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 547e176bc59SStefano Zampini ierr = VecScatterEnd(is->cctx,x,is->x,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 548b4319ba4SBarry Smith 549b4319ba4SBarry Smith /* multiply the local matrix */ 550b4319ba4SBarry Smith ierr = MatMult(is->A,is->x,is->y);CHKERRQ(ierr); 551b4319ba4SBarry Smith 552b4319ba4SBarry Smith /* scatter product back into global memory */ 5532dcb1b2aSMatthew Knepley ierr = VecSet(y,zero);CHKERRQ(ierr); 554e176bc59SStefano Zampini ierr = VecScatterBegin(is->rctx,is->y,y,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 555e176bc59SStefano Zampini ierr = VecScatterEnd(is->rctx,is->y,y,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 556b4319ba4SBarry Smith PetscFunctionReturn(0); 557b4319ba4SBarry Smith } 558b4319ba4SBarry Smith 559b4319ba4SBarry Smith #undef __FUNCT__ 5602e74eeadSLisandro Dalcin #define __FUNCT__ "MatMultAdd_IS" 561b7ce53b6SStefano Zampini PetscErrorCode MatMultAdd_IS(Mat A,Vec v1,Vec v2,Vec v3) 5622e74eeadSLisandro Dalcin { 563650997f4SStefano Zampini Vec temp_vec; 5642e74eeadSLisandro Dalcin PetscErrorCode ierr; 5652e74eeadSLisandro Dalcin 5662e74eeadSLisandro Dalcin PetscFunctionBegin; /* v3 = v2 + A * v1.*/ 567650997f4SStefano Zampini if (v3 != v2) { 568650997f4SStefano Zampini ierr = MatMult(A,v1,v3);CHKERRQ(ierr); 569650997f4SStefano Zampini ierr = VecAXPY(v3,1.0,v2);CHKERRQ(ierr); 570650997f4SStefano Zampini } else { 571650997f4SStefano Zampini ierr = VecDuplicate(v2,&temp_vec);CHKERRQ(ierr); 572650997f4SStefano Zampini ierr = MatMult(A,v1,temp_vec);CHKERRQ(ierr); 573650997f4SStefano Zampini ierr = VecAXPY(temp_vec,1.0,v2);CHKERRQ(ierr); 574650997f4SStefano Zampini ierr = VecCopy(temp_vec,v3);CHKERRQ(ierr); 575650997f4SStefano Zampini ierr = VecDestroy(&temp_vec);CHKERRQ(ierr); 576650997f4SStefano Zampini } 5772e74eeadSLisandro Dalcin PetscFunctionReturn(0); 5782e74eeadSLisandro Dalcin } 5792e74eeadSLisandro Dalcin 5802e74eeadSLisandro Dalcin #undef __FUNCT__ 5812e74eeadSLisandro Dalcin #define __FUNCT__ "MatMultTranspose_IS" 582e176bc59SStefano Zampini PetscErrorCode MatMultTranspose_IS(Mat A,Vec y,Vec x) 5832e74eeadSLisandro Dalcin { 5842e74eeadSLisandro Dalcin Mat_IS *is = (Mat_IS*)A->data; 5852e74eeadSLisandro Dalcin PetscErrorCode ierr; 5862e74eeadSLisandro Dalcin 587e176bc59SStefano Zampini PetscFunctionBegin; 5882e74eeadSLisandro Dalcin /* scatter the global vector x into the local work vector */ 589e176bc59SStefano Zampini ierr = VecScatterBegin(is->rctx,y,is->y,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 590e176bc59SStefano Zampini ierr = VecScatterEnd(is->rctx,y,is->y,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 5912e74eeadSLisandro Dalcin 5922e74eeadSLisandro Dalcin /* multiply the local matrix */ 593e176bc59SStefano Zampini ierr = MatMultTranspose(is->A,is->y,is->x);CHKERRQ(ierr); 5942e74eeadSLisandro Dalcin 5952e74eeadSLisandro Dalcin /* scatter product back into global vector */ 596e176bc59SStefano Zampini ierr = VecSet(x,0);CHKERRQ(ierr); 597e176bc59SStefano Zampini ierr = VecScatterBegin(is->cctx,is->x,x,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 598e176bc59SStefano Zampini ierr = VecScatterEnd(is->cctx,is->x,x,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 5992e74eeadSLisandro Dalcin PetscFunctionReturn(0); 6002e74eeadSLisandro Dalcin } 6012e74eeadSLisandro Dalcin 6022e74eeadSLisandro Dalcin #undef __FUNCT__ 6032e74eeadSLisandro Dalcin #define __FUNCT__ "MatMultTransposeAdd_IS" 6042e74eeadSLisandro Dalcin PetscErrorCode MatMultTransposeAdd_IS(Mat A,Vec v1,Vec v2,Vec v3) 6052e74eeadSLisandro Dalcin { 606650997f4SStefano Zampini Vec temp_vec; 6072e74eeadSLisandro Dalcin PetscErrorCode ierr; 6082e74eeadSLisandro Dalcin 6092e74eeadSLisandro Dalcin PetscFunctionBegin; /* v3 = v2 + A' * v1.*/ 610650997f4SStefano Zampini if (v3 != v2) { 611650997f4SStefano Zampini ierr = MatMultTranspose(A,v1,v3);CHKERRQ(ierr); 612650997f4SStefano Zampini ierr = VecAXPY(v3,1.0,v2);CHKERRQ(ierr); 613650997f4SStefano Zampini } else { 614650997f4SStefano Zampini ierr = VecDuplicate(v2,&temp_vec);CHKERRQ(ierr); 615650997f4SStefano Zampini ierr = MatMultTranspose(A,v1,temp_vec);CHKERRQ(ierr); 616650997f4SStefano Zampini ierr = VecAXPY(temp_vec,1.0,v2);CHKERRQ(ierr); 617650997f4SStefano Zampini ierr = VecCopy(temp_vec,v3);CHKERRQ(ierr); 618650997f4SStefano Zampini ierr = VecDestroy(&temp_vec);CHKERRQ(ierr); 619650997f4SStefano Zampini } 6202e74eeadSLisandro Dalcin PetscFunctionReturn(0); 6212e74eeadSLisandro Dalcin } 6222e74eeadSLisandro Dalcin 6232e74eeadSLisandro Dalcin #undef __FUNCT__ 624b4319ba4SBarry Smith #define __FUNCT__ "MatView_IS" 625dfbe8321SBarry Smith PetscErrorCode MatView_IS(Mat A,PetscViewer viewer) 626b4319ba4SBarry Smith { 627b4319ba4SBarry Smith Mat_IS *a = (Mat_IS*)A->data; 628dfbe8321SBarry Smith PetscErrorCode ierr; 629b4319ba4SBarry Smith PetscViewer sviewer; 630b4319ba4SBarry Smith 631b4319ba4SBarry Smith PetscFunctionBegin; 6323f08860eSBarry Smith ierr = PetscViewerGetSubViewer(viewer,PETSC_COMM_SELF,&sviewer);CHKERRQ(ierr); 633b4319ba4SBarry Smith ierr = MatView(a->A,sviewer);CHKERRQ(ierr); 6343f08860eSBarry Smith ierr = PetscViewerRestoreSubViewer(viewer,PETSC_COMM_SELF,&sviewer);CHKERRQ(ierr); 635b4319ba4SBarry Smith PetscFunctionReturn(0); 636b4319ba4SBarry Smith } 637b4319ba4SBarry Smith 638b4319ba4SBarry Smith #undef __FUNCT__ 639b4319ba4SBarry Smith #define __FUNCT__ "MatSetLocalToGlobalMapping_IS" 640784ac674SJed Brown PetscErrorCode MatSetLocalToGlobalMapping_IS(Mat A,ISLocalToGlobalMapping rmapping,ISLocalToGlobalMapping cmapping) 641b4319ba4SBarry Smith { 642dfbe8321SBarry Smith PetscErrorCode ierr; 643e176bc59SStefano Zampini PetscInt nr,rbs,nc,cbs; 644b4319ba4SBarry Smith Mat_IS *is = (Mat_IS*)A->data; 645b4319ba4SBarry Smith IS from,to; 646e176bc59SStefano Zampini Vec cglobal,rglobal; 647b4319ba4SBarry Smith 648b4319ba4SBarry Smith PetscFunctionBegin; 649784ac674SJed Brown PetscCheckSameComm(A,1,rmapping,2); 650e176bc59SStefano Zampini PetscCheckSameComm(A,1,cmapping,3); 6513bbff08aSStefano Zampini /* Destroy any previous data */ 65270cf5478SStefano Zampini ierr = VecDestroy(&is->x);CHKERRQ(ierr); 65370cf5478SStefano Zampini ierr = VecDestroy(&is->y);CHKERRQ(ierr); 654e176bc59SStefano Zampini ierr = VecScatterDestroy(&is->rctx);CHKERRQ(ierr); 655e176bc59SStefano Zampini ierr = VecScatterDestroy(&is->cctx);CHKERRQ(ierr); 6561c47cb0fSStefano Zampini ierr = MatDestroy(&is->A);CHKERRQ(ierr); 65728f4e0baSStefano Zampini ierr = PetscSFDestroy(&is->sf);CHKERRQ(ierr); 65828f4e0baSStefano Zampini ierr = PetscFree2(is->sf_rootdata,is->sf_leafdata);CHKERRQ(ierr); 6593bbff08aSStefano Zampini 6603bbff08aSStefano Zampini /* Setup Layout and set local to global maps */ 661fc27028aSStefano Zampini ierr = PetscLayoutSetUp(A->rmap);CHKERRQ(ierr); 662fc27028aSStefano Zampini ierr = PetscLayoutSetUp(A->cmap);CHKERRQ(ierr); 663fa7f1dd8SStefano Zampini ierr = PetscLayoutSetISLocalToGlobalMapping(A->rmap,rmapping);CHKERRQ(ierr); 664fa7f1dd8SStefano Zampini ierr = PetscLayoutSetISLocalToGlobalMapping(A->cmap,cmapping);CHKERRQ(ierr); 665b4319ba4SBarry Smith 666b4319ba4SBarry Smith /* Create the local matrix A */ 667e176bc59SStefano Zampini ierr = ISLocalToGlobalMappingGetSize(rmapping,&nr);CHKERRQ(ierr); 668e176bc59SStefano Zampini ierr = ISLocalToGlobalMappingGetBlockSize(rmapping,&rbs);CHKERRQ(ierr); 669e176bc59SStefano Zampini ierr = ISLocalToGlobalMappingGetSize(cmapping,&nc);CHKERRQ(ierr); 670e176bc59SStefano Zampini ierr = ISLocalToGlobalMappingGetBlockSize(cmapping,&cbs);CHKERRQ(ierr); 671f69a0ea3SMatthew Knepley ierr = MatCreate(PETSC_COMM_SELF,&is->A);CHKERRQ(ierr); 672e176bc59SStefano Zampini ierr = MatSetType(is->A,MATAIJ);CHKERRQ(ierr); 673e176bc59SStefano Zampini ierr = MatSetSizes(is->A,nr,nc,nr,nc);CHKERRQ(ierr); 674e176bc59SStefano Zampini ierr = MatSetBlockSizes(is->A,rbs,cbs);CHKERRQ(ierr); 675ff130e51SJed Brown ierr = MatSetOptionsPrefix(is->A,((PetscObject)A)->prefix);CHKERRQ(ierr); 676ff130e51SJed Brown ierr = MatAppendOptionsPrefix(is->A,"is_");CHKERRQ(ierr); 677b4319ba4SBarry Smith ierr = MatSetFromOptions(is->A);CHKERRQ(ierr); 678b4319ba4SBarry Smith 679b4319ba4SBarry Smith /* Create the local work vectors */ 6803bbff08aSStefano Zampini ierr = MatCreateVecs(is->A,&is->x,&is->y);CHKERRQ(ierr); 681b4319ba4SBarry Smith 682e176bc59SStefano Zampini /* setup the global to local scatters */ 683e176bc59SStefano Zampini ierr = MatCreateVecs(A,&cglobal,&rglobal);CHKERRQ(ierr); 684e176bc59SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,nr,0,1,&to);CHKERRQ(ierr); 685784ac674SJed Brown ierr = ISLocalToGlobalMappingApplyIS(rmapping,to,&from);CHKERRQ(ierr); 686e176bc59SStefano Zampini ierr = VecScatterCreate(rglobal,from,is->y,to,&is->rctx);CHKERRQ(ierr); 687e176bc59SStefano Zampini if (rmapping != cmapping) { 688e176bc59SStefano Zampini ierr = ISDestroy(&to);CHKERRQ(ierr); 689e176bc59SStefano Zampini ierr = ISDestroy(&from);CHKERRQ(ierr); 690e176bc59SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,nc,0,1,&to);CHKERRQ(ierr); 691e176bc59SStefano Zampini ierr = ISLocalToGlobalMappingApplyIS(cmapping,to,&from);CHKERRQ(ierr); 692e176bc59SStefano Zampini ierr = VecScatterCreate(cglobal,from,is->x,to,&is->cctx);CHKERRQ(ierr); 693e176bc59SStefano Zampini } else { 694e176bc59SStefano Zampini ierr = PetscObjectReference((PetscObject)is->rctx);CHKERRQ(ierr); 695e176bc59SStefano Zampini is->cctx = is->rctx; 696e176bc59SStefano Zampini } 697e176bc59SStefano Zampini ierr = VecDestroy(&rglobal);CHKERRQ(ierr); 698e176bc59SStefano Zampini ierr = VecDestroy(&cglobal);CHKERRQ(ierr); 6996bf464f9SBarry Smith ierr = ISDestroy(&to);CHKERRQ(ierr); 7006bf464f9SBarry Smith ierr = ISDestroy(&from);CHKERRQ(ierr); 701b4319ba4SBarry Smith PetscFunctionReturn(0); 702b4319ba4SBarry Smith } 703b4319ba4SBarry Smith 7042e74eeadSLisandro Dalcin #undef __FUNCT__ 7052e74eeadSLisandro Dalcin #define __FUNCT__ "MatSetValues_IS" 7062e74eeadSLisandro Dalcin PetscErrorCode MatSetValues_IS(Mat mat, PetscInt m,const PetscInt *rows, PetscInt n,const PetscInt *cols, const PetscScalar *values, InsertMode addv) 7072e74eeadSLisandro Dalcin { 7082e74eeadSLisandro Dalcin Mat_IS *is = (Mat_IS*)mat->data; 7092e74eeadSLisandro Dalcin PetscInt rows_l[2048],cols_l[2048]; 7102e74eeadSLisandro Dalcin PetscErrorCode ierr; 7112e74eeadSLisandro Dalcin 7122e74eeadSLisandro Dalcin PetscFunctionBegin; 7132e74eeadSLisandro Dalcin #if defined(PETSC_USE_DEBUG) 714f23aa3ddSBarry Smith if (m > 2048 || n > 2048) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_SUP,"Number of row/column indices must be <= 2048: they are %D %D",m,n); 7152e74eeadSLisandro Dalcin #endif 7163bbff08aSStefano Zampini ierr = ISG2LMapApply(mat->rmap->mapping,m,rows,rows_l);CHKERRQ(ierr); 7173bbff08aSStefano Zampini ierr = ISG2LMapApply(mat->cmap->mapping,n,cols,cols_l);CHKERRQ(ierr); 7182e74eeadSLisandro Dalcin ierr = MatSetValues(is->A,m,rows_l,n,cols_l,values,addv);CHKERRQ(ierr); 7192e74eeadSLisandro Dalcin PetscFunctionReturn(0); 7202e74eeadSLisandro Dalcin } 7212e74eeadSLisandro Dalcin 722b4319ba4SBarry Smith #undef __FUNCT__ 723b4319ba4SBarry Smith #define __FUNCT__ "MatSetValuesLocal_IS" 72413f74950SBarry Smith PetscErrorCode MatSetValuesLocal_IS(Mat A,PetscInt m,const PetscInt *rows, PetscInt n,const PetscInt *cols,const PetscScalar *values,InsertMode addv) 725b4319ba4SBarry Smith { 726dfbe8321SBarry Smith PetscErrorCode ierr; 727b4319ba4SBarry Smith Mat_IS *is = (Mat_IS*)A->data; 728b4319ba4SBarry Smith 729b4319ba4SBarry Smith PetscFunctionBegin; 730b4319ba4SBarry Smith ierr = MatSetValues(is->A,m,rows,n,cols,values,addv);CHKERRQ(ierr); 731b4319ba4SBarry Smith PetscFunctionReturn(0); 732b4319ba4SBarry Smith } 733b4319ba4SBarry Smith 734b4319ba4SBarry Smith #undef __FUNCT__ 735f0006bf2SLisandro Dalcin #define __FUNCT__ "MatSetValuesBlockedLocal_IS" 736f0006bf2SLisandro Dalcin PetscErrorCode MatSetValuesBlockedLocal_IS(Mat A,PetscInt m,const PetscInt *rows, PetscInt n,const PetscInt *cols,const PetscScalar *values,InsertMode addv) 737f0006bf2SLisandro Dalcin { 738f0006bf2SLisandro Dalcin PetscErrorCode ierr; 739f0006bf2SLisandro Dalcin Mat_IS *is = (Mat_IS*)A->data; 740f0006bf2SLisandro Dalcin 741f0006bf2SLisandro Dalcin PetscFunctionBegin; 742f0006bf2SLisandro Dalcin ierr = MatSetValuesBlocked(is->A,m,rows,n,cols,values,addv);CHKERRQ(ierr); 743f0006bf2SLisandro Dalcin PetscFunctionReturn(0); 744f0006bf2SLisandro Dalcin } 745f0006bf2SLisandro Dalcin 746f0006bf2SLisandro Dalcin #undef __FUNCT__ 7472e74eeadSLisandro Dalcin #define __FUNCT__ "MatZeroRows_IS" 7482b40b63fSBarry Smith PetscErrorCode MatZeroRows_IS(Mat A,PetscInt n,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 7492e74eeadSLisandro Dalcin { 7500298fd71SBarry Smith PetscInt n_l = 0, *rows_l = NULL; 7512e74eeadSLisandro Dalcin PetscErrorCode ierr; 7522e74eeadSLisandro Dalcin 7532e74eeadSLisandro Dalcin PetscFunctionBegin; 754ce94432eSBarry Smith if (x && b) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"No support"); 7552e74eeadSLisandro Dalcin if (n) { 756785e854fSJed Brown ierr = PetscMalloc1(n,&rows_l);CHKERRQ(ierr); 7573bbff08aSStefano Zampini ierr = ISGlobalToLocalMappingApply(A->rmap->mapping,IS_GTOLM_DROP,n,rows,&n_l,rows_l);CHKERRQ(ierr); 7582e74eeadSLisandro Dalcin } 7592b40b63fSBarry Smith ierr = MatZeroRowsLocal(A,n_l,rows_l,diag,x,b);CHKERRQ(ierr); 760c31cb41cSBarry Smith ierr = PetscFree(rows_l);CHKERRQ(ierr); 7612e74eeadSLisandro Dalcin PetscFunctionReturn(0); 7622e74eeadSLisandro Dalcin } 7632e74eeadSLisandro Dalcin 7642e74eeadSLisandro Dalcin #undef __FUNCT__ 765b4319ba4SBarry Smith #define __FUNCT__ "MatZeroRowsLocal_IS" 7662b40b63fSBarry Smith PetscErrorCode MatZeroRowsLocal_IS(Mat A,PetscInt n,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 767b4319ba4SBarry Smith { 768b4319ba4SBarry Smith Mat_IS *is = (Mat_IS*)A->data; 769dfbe8321SBarry Smith PetscErrorCode ierr; 770f4df32b1SMatthew Knepley PetscInt i; 771b4319ba4SBarry Smith PetscScalar *array; 772b4319ba4SBarry Smith 773b4319ba4SBarry Smith PetscFunctionBegin; 774ce94432eSBarry Smith if (x && b) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"No support"); 775b4319ba4SBarry Smith { 776b4319ba4SBarry Smith /* 777b4319ba4SBarry Smith Set up is->x as a "counting vector". This is in order to MatMult_IS 778b4319ba4SBarry Smith work properly in the interface nodes. 779b4319ba4SBarry Smith */ 780b4319ba4SBarry Smith Vec counter; 781e176bc59SStefano Zampini ierr = MatCreateVecs(A,NULL,&counter);CHKERRQ(ierr); 782e176bc59SStefano Zampini ierr = VecSet(counter,0.);CHKERRQ(ierr); 783e176bc59SStefano Zampini ierr = VecSet(is->y,1.);CHKERRQ(ierr); 784e176bc59SStefano Zampini ierr = VecScatterBegin(is->rctx,is->y,counter,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 785e176bc59SStefano Zampini ierr = VecScatterEnd(is->rctx,is->y,counter,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 786e176bc59SStefano Zampini ierr = VecScatterBegin(is->rctx,counter,is->y,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 787e176bc59SStefano Zampini ierr = VecScatterEnd(is->rctx,counter,is->y,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 7886bf464f9SBarry Smith ierr = VecDestroy(&counter);CHKERRQ(ierr); 789b4319ba4SBarry Smith } 790958c9bccSBarry Smith if (!n) { 791b4319ba4SBarry Smith is->pure_neumann = PETSC_TRUE; 792b4319ba4SBarry Smith } else { 793b4319ba4SBarry Smith is->pure_neumann = PETSC_FALSE; 7942205254eSKarl Rupp 795e176bc59SStefano Zampini ierr = VecGetArray(is->y,&array);CHKERRQ(ierr); 7962b40b63fSBarry Smith ierr = MatZeroRows(is->A,n,rows,diag,0,0);CHKERRQ(ierr); 797b4319ba4SBarry Smith for (i=0; i<n; i++) { 798f4df32b1SMatthew Knepley ierr = MatSetValue(is->A,rows[i],rows[i],diag/(array[rows[i]]),INSERT_VALUES);CHKERRQ(ierr); 799b4319ba4SBarry Smith } 800b4319ba4SBarry Smith ierr = MatAssemblyBegin(is->A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 801b4319ba4SBarry Smith ierr = MatAssemblyEnd(is->A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 802e176bc59SStefano Zampini ierr = VecRestoreArray(is->y,&array);CHKERRQ(ierr); 803b4319ba4SBarry Smith } 804b4319ba4SBarry Smith PetscFunctionReturn(0); 805b4319ba4SBarry Smith } 806b4319ba4SBarry Smith 807b4319ba4SBarry Smith #undef __FUNCT__ 808b4319ba4SBarry Smith #define __FUNCT__ "MatAssemblyBegin_IS" 809dfbe8321SBarry Smith PetscErrorCode MatAssemblyBegin_IS(Mat A,MatAssemblyType type) 810b4319ba4SBarry Smith { 811b4319ba4SBarry Smith Mat_IS *is = (Mat_IS*)A->data; 812dfbe8321SBarry Smith PetscErrorCode ierr; 813b4319ba4SBarry Smith 814b4319ba4SBarry Smith PetscFunctionBegin; 815b4319ba4SBarry Smith ierr = MatAssemblyBegin(is->A,type);CHKERRQ(ierr); 816b4319ba4SBarry Smith PetscFunctionReturn(0); 817b4319ba4SBarry Smith } 818b4319ba4SBarry Smith 819b4319ba4SBarry Smith #undef __FUNCT__ 820b4319ba4SBarry Smith #define __FUNCT__ "MatAssemblyEnd_IS" 821dfbe8321SBarry Smith PetscErrorCode MatAssemblyEnd_IS(Mat A,MatAssemblyType type) 822b4319ba4SBarry Smith { 823b4319ba4SBarry Smith Mat_IS *is = (Mat_IS*)A->data; 824dfbe8321SBarry Smith PetscErrorCode ierr; 825b4319ba4SBarry Smith 826b4319ba4SBarry Smith PetscFunctionBegin; 827b4319ba4SBarry Smith ierr = MatAssemblyEnd(is->A,type);CHKERRQ(ierr); 828b4319ba4SBarry Smith PetscFunctionReturn(0); 829b4319ba4SBarry Smith } 830b4319ba4SBarry Smith 831b4319ba4SBarry Smith #undef __FUNCT__ 832b4319ba4SBarry Smith #define __FUNCT__ "MatISGetLocalMat_IS" 8337087cfbeSBarry Smith PetscErrorCode MatISGetLocalMat_IS(Mat mat,Mat *local) 834b4319ba4SBarry Smith { 835b4319ba4SBarry Smith Mat_IS *is = (Mat_IS*)mat->data; 836b4319ba4SBarry Smith 837b4319ba4SBarry Smith PetscFunctionBegin; 838b4319ba4SBarry Smith *local = is->A; 839b4319ba4SBarry Smith PetscFunctionReturn(0); 840b4319ba4SBarry Smith } 841b4319ba4SBarry Smith 842b4319ba4SBarry Smith #undef __FUNCT__ 843b4319ba4SBarry Smith #define __FUNCT__ "MatISGetLocalMat" 844b4319ba4SBarry Smith /*@ 845b4319ba4SBarry Smith MatISGetLocalMat - Gets the local matrix stored inside a MATIS matrix. 846b4319ba4SBarry Smith 847b4319ba4SBarry Smith Input Parameter: 848b4319ba4SBarry Smith . mat - the matrix 849b4319ba4SBarry Smith 850b4319ba4SBarry Smith Output Parameter: 851eb82efa4SStefano Zampini . local - the local matrix 852b4319ba4SBarry Smith 853b4319ba4SBarry Smith Level: advanced 854b4319ba4SBarry Smith 855b4319ba4SBarry Smith Notes: 856b4319ba4SBarry Smith This can be called if you have precomputed the nonzero structure of the 857b4319ba4SBarry Smith matrix and want to provide it to the inner matrix object to improve the performance 858b4319ba4SBarry Smith of the MatSetValues() operation. 859b4319ba4SBarry Smith 860b4319ba4SBarry Smith .seealso: MATIS 861b4319ba4SBarry Smith @*/ 8627087cfbeSBarry Smith PetscErrorCode MatISGetLocalMat(Mat mat,Mat *local) 863b4319ba4SBarry Smith { 8644ac538c5SBarry Smith PetscErrorCode ierr; 865b4319ba4SBarry Smith 866b4319ba4SBarry Smith PetscFunctionBegin; 8670700a824SBarry Smith PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 868b4319ba4SBarry Smith PetscValidPointer(local,2); 8694ac538c5SBarry Smith ierr = PetscUseMethod(mat,"MatISGetLocalMat_C",(Mat,Mat*),(mat,local));CHKERRQ(ierr); 870b4319ba4SBarry Smith PetscFunctionReturn(0); 871b4319ba4SBarry Smith } 872b4319ba4SBarry Smith 8733b03a366Sstefano_zampini #undef __FUNCT__ 8743b03a366Sstefano_zampini #define __FUNCT__ "MatISSetLocalMat_IS" 8753b03a366Sstefano_zampini PetscErrorCode MatISSetLocalMat_IS(Mat mat,Mat local) 8763b03a366Sstefano_zampini { 8773b03a366Sstefano_zampini Mat_IS *is = (Mat_IS*)mat->data; 8783b03a366Sstefano_zampini PetscInt nrows,ncols,orows,ocols; 8793b03a366Sstefano_zampini PetscErrorCode ierr; 8803b03a366Sstefano_zampini 8813b03a366Sstefano_zampini PetscFunctionBegin; 8824e4c7dbeSStefano Zampini if (is->A) { 8833b03a366Sstefano_zampini ierr = MatGetSize(is->A,&orows,&ocols);CHKERRQ(ierr); 8843b03a366Sstefano_zampini ierr = MatGetSize(local,&nrows,&ncols);CHKERRQ(ierr); 885f23aa3ddSBarry Smith 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)\n",orows,ocols,nrows,ncols); 8864e4c7dbeSStefano Zampini } 8873b03a366Sstefano_zampini ierr = PetscObjectReference((PetscObject)local);CHKERRQ(ierr); 8883b03a366Sstefano_zampini ierr = MatDestroy(&is->A);CHKERRQ(ierr); 8893b03a366Sstefano_zampini is->A = local; 8903b03a366Sstefano_zampini PetscFunctionReturn(0); 8913b03a366Sstefano_zampini } 8923b03a366Sstefano_zampini 8933b03a366Sstefano_zampini #undef __FUNCT__ 8943b03a366Sstefano_zampini #define __FUNCT__ "MatISSetLocalMat" 8953b03a366Sstefano_zampini /*@ 896eb82efa4SStefano Zampini MatISSetLocalMat - Replace the local matrix stored inside a MATIS object. 8973b03a366Sstefano_zampini 8983b03a366Sstefano_zampini Input Parameter: 8993b03a366Sstefano_zampini . mat - the matrix 900eb82efa4SStefano Zampini . local - the local matrix 9013b03a366Sstefano_zampini 9023b03a366Sstefano_zampini Output Parameter: 9033b03a366Sstefano_zampini 9043b03a366Sstefano_zampini Level: advanced 9053b03a366Sstefano_zampini 9063b03a366Sstefano_zampini Notes: 9073b03a366Sstefano_zampini This can be called if you have precomputed the local matrix and 9083b03a366Sstefano_zampini want to provide it to the matrix object MATIS. 9093b03a366Sstefano_zampini 9103b03a366Sstefano_zampini .seealso: MATIS 9113b03a366Sstefano_zampini @*/ 9123b03a366Sstefano_zampini PetscErrorCode MatISSetLocalMat(Mat mat,Mat local) 9133b03a366Sstefano_zampini { 9143b03a366Sstefano_zampini PetscErrorCode ierr; 9153b03a366Sstefano_zampini 9163b03a366Sstefano_zampini PetscFunctionBegin; 9173b03a366Sstefano_zampini PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 918b7ce53b6SStefano Zampini PetscValidHeaderSpecific(local,MAT_CLASSID,2); 9193b03a366Sstefano_zampini ierr = PetscUseMethod(mat,"MatISSetLocalMat_C",(Mat,Mat),(mat,local));CHKERRQ(ierr); 9203b03a366Sstefano_zampini PetscFunctionReturn(0); 9213b03a366Sstefano_zampini } 9223b03a366Sstefano_zampini 9236726f965SBarry Smith #undef __FUNCT__ 9246726f965SBarry Smith #define __FUNCT__ "MatZeroEntries_IS" 9256726f965SBarry Smith PetscErrorCode MatZeroEntries_IS(Mat A) 9266726f965SBarry Smith { 9276726f965SBarry Smith Mat_IS *a = (Mat_IS*)A->data; 9286726f965SBarry Smith PetscErrorCode ierr; 9296726f965SBarry Smith 9306726f965SBarry Smith PetscFunctionBegin; 9316726f965SBarry Smith ierr = MatZeroEntries(a->A);CHKERRQ(ierr); 9326726f965SBarry Smith PetscFunctionReturn(0); 9336726f965SBarry Smith } 9346726f965SBarry Smith 9356726f965SBarry Smith #undef __FUNCT__ 9362e74eeadSLisandro Dalcin #define __FUNCT__ "MatScale_IS" 9372e74eeadSLisandro Dalcin PetscErrorCode MatScale_IS(Mat A,PetscScalar a) 9382e74eeadSLisandro Dalcin { 9392e74eeadSLisandro Dalcin Mat_IS *is = (Mat_IS*)A->data; 9402e74eeadSLisandro Dalcin PetscErrorCode ierr; 9412e74eeadSLisandro Dalcin 9422e74eeadSLisandro Dalcin PetscFunctionBegin; 9432e74eeadSLisandro Dalcin ierr = MatScale(is->A,a);CHKERRQ(ierr); 9442e74eeadSLisandro Dalcin PetscFunctionReturn(0); 9452e74eeadSLisandro Dalcin } 9462e74eeadSLisandro Dalcin 9472e74eeadSLisandro Dalcin #undef __FUNCT__ 9482e74eeadSLisandro Dalcin #define __FUNCT__ "MatGetDiagonal_IS" 9492e74eeadSLisandro Dalcin PetscErrorCode MatGetDiagonal_IS(Mat A, Vec v) 9502e74eeadSLisandro Dalcin { 9512e74eeadSLisandro Dalcin Mat_IS *is = (Mat_IS*)A->data; 9522e74eeadSLisandro Dalcin PetscErrorCode ierr; 9532e74eeadSLisandro Dalcin 9542e74eeadSLisandro Dalcin PetscFunctionBegin; 9552e74eeadSLisandro Dalcin /* get diagonal of the local matrix */ 956e176bc59SStefano Zampini ierr = MatGetDiagonal(is->A,is->y);CHKERRQ(ierr); 9572e74eeadSLisandro Dalcin 9582e74eeadSLisandro Dalcin /* scatter diagonal back into global vector */ 9592e74eeadSLisandro Dalcin ierr = VecSet(v,0);CHKERRQ(ierr); 960e176bc59SStefano Zampini ierr = VecScatterBegin(is->rctx,is->y,v,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 961e176bc59SStefano Zampini ierr = VecScatterEnd(is->rctx,is->y,v,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 9622e74eeadSLisandro Dalcin PetscFunctionReturn(0); 9632e74eeadSLisandro Dalcin } 9642e74eeadSLisandro Dalcin 9652e74eeadSLisandro Dalcin #undef __FUNCT__ 9666726f965SBarry Smith #define __FUNCT__ "MatSetOption_IS" 967ace3abfcSBarry Smith PetscErrorCode MatSetOption_IS(Mat A,MatOption op,PetscBool flg) 9686726f965SBarry Smith { 9696726f965SBarry Smith Mat_IS *a = (Mat_IS*)A->data; 9706726f965SBarry Smith PetscErrorCode ierr; 9716726f965SBarry Smith 9726726f965SBarry Smith PetscFunctionBegin; 9734e0d8c25SBarry Smith ierr = MatSetOption(a->A,op,flg);CHKERRQ(ierr); 9746726f965SBarry Smith PetscFunctionReturn(0); 9756726f965SBarry Smith } 9766726f965SBarry Smith 977284134d9SBarry Smith #undef __FUNCT__ 978284134d9SBarry Smith #define __FUNCT__ "MatCreateIS" 979284134d9SBarry Smith /*@ 980284134d9SBarry Smith MatCreateIS - Creates a "process" unassmembled matrix, it is assembled on each 981284134d9SBarry Smith process but not across processes. 982284134d9SBarry Smith 983284134d9SBarry Smith Input Parameters: 984284134d9SBarry Smith + comm - MPI communicator that will share the matrix 985e176bc59SStefano Zampini . bs - block size of the matrix 986df3898eeSBarry Smith . m,n,M,N - local and/or global sizes of the left and right vector used in matrix vector products 987e176bc59SStefano Zampini . rmap - local to global map for rows 988e176bc59SStefano Zampini - cmap - local to global map for cols 989284134d9SBarry Smith 990284134d9SBarry Smith Output Parameter: 991284134d9SBarry Smith . A - the resulting matrix 992284134d9SBarry Smith 9938e6c10adSSatish Balay Level: advanced 9948e6c10adSSatish Balay 995284134d9SBarry Smith Notes: See MATIS for more details 9968cda6cd7SBarry Smith m and n are NOT related to the size of the map, they are the size of the part of the vector owned 997e176bc59SStefano Zampini by that process. The sizes of rmap and cmap define the size of the local matrices. 998e176bc59SStefano Zampini If either rmap or cmap are NULL, than the matrix is assumed to be square 999284134d9SBarry Smith 1000284134d9SBarry Smith .seealso: MATIS, MatSetLocalToGlobalMapping() 1001284134d9SBarry Smith @*/ 1002e176bc59SStefano Zampini PetscErrorCode MatCreateIS(MPI_Comm comm,PetscInt bs,PetscInt m,PetscInt n,PetscInt M,PetscInt N,ISLocalToGlobalMapping rmap,ISLocalToGlobalMapping cmap,Mat *A) 1003284134d9SBarry Smith { 1004284134d9SBarry Smith PetscErrorCode ierr; 1005284134d9SBarry Smith 1006284134d9SBarry Smith PetscFunctionBegin; 1007e176bc59SStefano Zampini if (!rmap && !cmap) SETERRQ(comm,PETSC_ERR_USER,"You need to provide at least one of the mapping"); 1008284134d9SBarry Smith ierr = MatCreate(comm,A);CHKERRQ(ierr); 1009d3ee2243SStefano Zampini ierr = MatSetBlockSize(*A,bs);CHKERRQ(ierr); 1010284134d9SBarry Smith ierr = MatSetSizes(*A,m,n,M,N);CHKERRQ(ierr); 1011284134d9SBarry Smith ierr = MatSetType(*A,MATIS);CHKERRQ(ierr); 10123b03a366Sstefano_zampini ierr = MatSetUp(*A);CHKERRQ(ierr); 1013e176bc59SStefano Zampini if (rmap && cmap) { 1014e176bc59SStefano Zampini ierr = MatSetLocalToGlobalMapping(*A,rmap,cmap);CHKERRQ(ierr); 1015e176bc59SStefano Zampini } else if (!rmap) { 1016e176bc59SStefano Zampini ierr = MatSetLocalToGlobalMapping(*A,cmap,cmap);CHKERRQ(ierr); 1017e176bc59SStefano Zampini } else { 1018e176bc59SStefano Zampini ierr = MatSetLocalToGlobalMapping(*A,rmap,rmap);CHKERRQ(ierr); 1019e176bc59SStefano Zampini } 1020284134d9SBarry Smith PetscFunctionReturn(0); 1021284134d9SBarry Smith } 1022284134d9SBarry Smith 1023b4319ba4SBarry Smith /*MC 1024eb82efa4SStefano Zampini MATIS - MATIS = "is" - A matrix type to be used for using the non-overlapping domain decomposition type preconditioners (e.g. PCBDDC). 1025b4319ba4SBarry Smith This stores the matrices in globally unassembled form. Each processor 1026b4319ba4SBarry Smith assembles only its local Neumann problem and the parallel matrix vector 1027b4319ba4SBarry Smith product is handled "implicitly". 1028b4319ba4SBarry Smith 1029b4319ba4SBarry Smith Operations Provided: 10306726f965SBarry Smith + MatMult() 10312e74eeadSLisandro Dalcin . MatMultAdd() 10322e74eeadSLisandro Dalcin . MatMultTranspose() 10332e74eeadSLisandro Dalcin . MatMultTransposeAdd() 10346726f965SBarry Smith . MatZeroEntries() 10356726f965SBarry Smith . MatSetOption() 10362e74eeadSLisandro Dalcin . MatZeroRows() 10376726f965SBarry Smith . MatZeroRowsLocal() 10382e74eeadSLisandro Dalcin . MatSetValues() 10396726f965SBarry Smith . MatSetValuesLocal() 10402e74eeadSLisandro Dalcin . MatScale() 10412e74eeadSLisandro Dalcin . MatGetDiagonal() 10426726f965SBarry Smith - MatSetLocalToGlobalMapping() 1043b4319ba4SBarry Smith 1044b4319ba4SBarry Smith Options Database Keys: 1045b4319ba4SBarry Smith . -mat_type is - sets the matrix type to "is" during a call to MatSetFromOptions() 1046b4319ba4SBarry Smith 1047b4319ba4SBarry Smith Notes: Options prefix for the inner matrix are given by -is_mat_xxx 1048b4319ba4SBarry Smith 1049b4319ba4SBarry Smith You must call MatSetLocalToGlobalMapping() before using this matrix type. 1050b4319ba4SBarry Smith 1051b4319ba4SBarry Smith You can do matrix preallocation on the local matrix after you obtain it with 1052eb82efa4SStefano Zampini MatISGetLocalMat(); otherwise, you could use MatISSetPreallocation() 1053b4319ba4SBarry Smith 1054b4319ba4SBarry Smith Level: advanced 1055b4319ba4SBarry Smith 1056eb82efa4SStefano Zampini .seealso: Mat, MatISGetLocalMat(), MatSetLocalToGlobalMapping(), MatISSetPreallocation(), PCBDDC 1057b4319ba4SBarry Smith 1058b4319ba4SBarry Smith M*/ 1059b4319ba4SBarry Smith 1060b4319ba4SBarry Smith #undef __FUNCT__ 1061b4319ba4SBarry Smith #define __FUNCT__ "MatCreate_IS" 10628cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatCreate_IS(Mat A) 1063b4319ba4SBarry Smith { 1064dfbe8321SBarry Smith PetscErrorCode ierr; 1065b4319ba4SBarry Smith Mat_IS *b; 1066b4319ba4SBarry Smith 1067b4319ba4SBarry Smith PetscFunctionBegin; 1068b00a9115SJed Brown ierr = PetscNewLog(A,&b);CHKERRQ(ierr); 1069b4319ba4SBarry Smith A->data = (void*)b; 1070b4319ba4SBarry Smith 1071e176bc59SStefano Zampini /* matrix ops */ 1072e176bc59SStefano Zampini ierr = PetscMemzero(A->ops,sizeof(struct _MatOps));CHKERRQ(ierr); 1073b4319ba4SBarry Smith A->ops->mult = MatMult_IS; 10742e74eeadSLisandro Dalcin A->ops->multadd = MatMultAdd_IS; 10752e74eeadSLisandro Dalcin A->ops->multtranspose = MatMultTranspose_IS; 10762e74eeadSLisandro Dalcin A->ops->multtransposeadd = MatMultTransposeAdd_IS; 1077b4319ba4SBarry Smith A->ops->destroy = MatDestroy_IS; 1078b4319ba4SBarry Smith A->ops->setlocaltoglobalmapping = MatSetLocalToGlobalMapping_IS; 10792e74eeadSLisandro Dalcin A->ops->setvalues = MatSetValues_IS; 1080b4319ba4SBarry Smith A->ops->setvalueslocal = MatSetValuesLocal_IS; 1081f0006bf2SLisandro Dalcin A->ops->setvaluesblockedlocal = MatSetValuesBlockedLocal_IS; 10822e74eeadSLisandro Dalcin A->ops->zerorows = MatZeroRows_IS; 1083b4319ba4SBarry Smith A->ops->zerorowslocal = MatZeroRowsLocal_IS; 1084b4319ba4SBarry Smith A->ops->assemblybegin = MatAssemblyBegin_IS; 1085b4319ba4SBarry Smith A->ops->assemblyend = MatAssemblyEnd_IS; 1086b4319ba4SBarry Smith A->ops->view = MatView_IS; 10876726f965SBarry Smith A->ops->zeroentries = MatZeroEntries_IS; 10882e74eeadSLisandro Dalcin A->ops->scale = MatScale_IS; 10892e74eeadSLisandro Dalcin A->ops->getdiagonal = MatGetDiagonal_IS; 10906726f965SBarry Smith A->ops->setoption = MatSetOption_IS; 109169796d55SStefano Zampini A->ops->ishermitian = MatIsHermitian_IS; 109269796d55SStefano Zampini A->ops->issymmetric = MatIsSymmetric_IS; 1093ad6194a2SStefano Zampini A->ops->duplicate = MatDuplicate_IS; 1094b4319ba4SBarry Smith 1095b7ce53b6SStefano Zampini /* special MATIS functions */ 1096bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatISGetLocalMat_C",MatISGetLocalMat_IS);CHKERRQ(ierr); 1097bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatISSetLocalMat_C",MatISSetLocalMat_IS);CHKERRQ(ierr); 1098b7ce53b6SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatISGetMPIXAIJ_C",MatISGetMPIXAIJ_IS);CHKERRQ(ierr); 10992e1947a5SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatISSetPreallocation_C",MatISSetPreallocation_IS);CHKERRQ(ierr); 1100cf0a3239SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatISSetUpSF_C",MatISSetUpSF_IS);CHKERRQ(ierr); 110117667f90SBarry Smith ierr = PetscObjectChangeTypeName((PetscObject)A,MATIS);CHKERRQ(ierr); 1102b4319ba4SBarry Smith PetscFunctionReturn(0); 1103b4319ba4SBarry Smith } 1104