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*/ 1628f4e0baSStefano Zampini 17a72627d2SStefano Zampini static PetscErrorCode MatISComputeSF_Private(Mat); 18a72627d2SStefano Zampini 1928f4e0baSStefano Zampini #undef __FUNCT__ 2028f4e0baSStefano Zampini #define __FUNCT__ "MatISComputeSF_Private" 21a72627d2SStefano Zampini static PetscErrorCode MatISComputeSF_Private(Mat B) 2228f4e0baSStefano Zampini { 2328f4e0baSStefano Zampini Mat_IS *matis = (Mat_IS*)(B->data); 2428f4e0baSStefano Zampini const PetscInt *gidxs; 2528f4e0baSStefano Zampini PetscErrorCode ierr; 2628f4e0baSStefano Zampini 2728f4e0baSStefano Zampini PetscFunctionBegin; 2828f4e0baSStefano Zampini ierr = MatGetSize(matis->A,&matis->sf_nleaves,NULL);CHKERRQ(ierr); 2928f4e0baSStefano Zampini ierr = MatGetLocalSize(B,&matis->sf_nroots,NULL);CHKERRQ(ierr); 3028f4e0baSStefano Zampini ierr = PetscSFCreate(PetscObjectComm((PetscObject)B),&matis->sf);CHKERRQ(ierr); 313bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(B->rmap->mapping,&gidxs);CHKERRQ(ierr); 3228f4e0baSStefano Zampini /* PETSC_OWN_POINTER refers to ilocal which is NULL */ 3328f4e0baSStefano Zampini ierr = PetscSFSetGraphLayout(matis->sf,B->rmap,matis->sf_nleaves,NULL,PETSC_OWN_POINTER,gidxs);CHKERRQ(ierr); 343bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(B->rmap->mapping,&gidxs);CHKERRQ(ierr); 3528f4e0baSStefano Zampini ierr = PetscMalloc2(matis->sf_nroots,&matis->sf_rootdata,matis->sf_nleaves,&matis->sf_leafdata);CHKERRQ(ierr); 3628f4e0baSStefano Zampini PetscFunctionReturn(0); 3728f4e0baSStefano Zampini } 382e1947a5SStefano Zampini 392e1947a5SStefano Zampini #undef __FUNCT__ 402e1947a5SStefano Zampini #define __FUNCT__ "MatISSetPreallocation" 41eb82efa4SStefano Zampini /*@ 42a88811baSStefano Zampini MatISSetPreallocation - Preallocates memory for a MATIS parallel matrix. 43a88811baSStefano Zampini 44a88811baSStefano Zampini Collective on MPI_Comm 45a88811baSStefano Zampini 46a88811baSStefano Zampini Input Parameters: 47a88811baSStefano Zampini + B - the matrix 48a88811baSStefano Zampini . d_nz - number of nonzeros per row in DIAGONAL portion of local submatrix 49a88811baSStefano Zampini (same value is used for all local rows) 50a88811baSStefano Zampini . d_nnz - array containing the number of nonzeros in the various rows of the 51a88811baSStefano Zampini DIAGONAL portion of the local submatrix (possibly different for each row) 52a88811baSStefano Zampini or NULL, if d_nz is used to specify the nonzero structure. 53a88811baSStefano Zampini The size of this array is equal to the number of local rows, i.e 'm'. 54a88811baSStefano Zampini For matrices that will be factored, you must leave room for (and set) 55a88811baSStefano Zampini the diagonal entry even if it is zero. 56a88811baSStefano Zampini . o_nz - number of nonzeros per row in the OFF-DIAGONAL portion of local 57a88811baSStefano Zampini submatrix (same value is used for all local rows). 58a88811baSStefano Zampini - o_nnz - array containing the number of nonzeros in the various rows of the 59a88811baSStefano Zampini OFF-DIAGONAL portion of the local submatrix (possibly different for 60a88811baSStefano Zampini each row) or NULL, if o_nz is used to specify the nonzero 61a88811baSStefano Zampini structure. The size of this array is equal to the number 62a88811baSStefano Zampini of local rows, i.e 'm'. 63a88811baSStefano Zampini 64a88811baSStefano Zampini If the *_nnz parameter is given then the *_nz parameter is ignored 65a88811baSStefano Zampini 66a88811baSStefano Zampini Level: intermediate 67a88811baSStefano Zampini 68a88811baSStefano Zampini Notes: This function has the same interface as the MPIAIJ preallocation routine in order to simplify the transition 69a88811baSStefano Zampini from the asssembled format to the unassembled one. It overestimates the preallocation of MATIS local 70a88811baSStefano Zampini matrices; for exact preallocation, the user should set the preallocation directly on local matrix objects. 71a88811baSStefano Zampini 72a88811baSStefano Zampini .keywords: matrix 73a88811baSStefano Zampini 74a88811baSStefano Zampini .seealso: MatCreate(), MatCreateIS(), MatMPIAIJSetPreallocation(), MatISGetLocalMat() 75a88811baSStefano Zampini @*/ 762e1947a5SStefano Zampini PetscErrorCode MatISSetPreallocation(Mat B,PetscInt d_nz,const PetscInt d_nnz[],PetscInt o_nz,const PetscInt o_nnz[]) 772e1947a5SStefano Zampini { 782e1947a5SStefano Zampini PetscErrorCode ierr; 792e1947a5SStefano Zampini 802e1947a5SStefano Zampini PetscFunctionBegin; 812e1947a5SStefano Zampini PetscValidHeaderSpecific(B,MAT_CLASSID,1); 822e1947a5SStefano Zampini PetscValidType(B,1); 832e1947a5SStefano Zampini ierr = PetscTryMethod(B,"MatISSetPreallocation_C",(Mat,PetscInt,const PetscInt[],PetscInt,const PetscInt[]),(B,d_nz,d_nnz,o_nz,o_nnz));CHKERRQ(ierr); 842e1947a5SStefano Zampini PetscFunctionReturn(0); 852e1947a5SStefano Zampini } 862e1947a5SStefano Zampini 872e1947a5SStefano Zampini #undef __FUNCT__ 882e1947a5SStefano Zampini #define __FUNCT__ "MatISSetPreallocation_IS" 892e1947a5SStefano Zampini PetscErrorCode MatISSetPreallocation_IS(Mat B,PetscInt d_nz,const PetscInt d_nnz[],PetscInt o_nz,const PetscInt o_nnz[]) 902e1947a5SStefano Zampini { 912e1947a5SStefano Zampini Mat_IS *matis = (Mat_IS*)(B->data); 9228f4e0baSStefano Zampini PetscInt bs,i,nlocalcols; 932e1947a5SStefano Zampini PetscErrorCode ierr; 942e1947a5SStefano Zampini 952e1947a5SStefano Zampini PetscFunctionBegin; 966c4ed002SBarry Smith if (!matis->A) SETERRQ(PetscObjectComm((PetscObject)B),PETSC_ERR_SUP,"You should first call MatSetLocalToGlobalMapping"); 9728f4e0baSStefano Zampini if (!matis->sf) { /* setup SF if not yet created and allocate rootdata and leafdata */ 9828f4e0baSStefano Zampini ierr = MatISComputeSF_Private(B);CHKERRQ(ierr); 9928f4e0baSStefano Zampini } 1002e1947a5SStefano Zampini if (!d_nnz) { 10128f4e0baSStefano Zampini for (i=0;i<matis->sf_nroots;i++) matis->sf_rootdata[i] = d_nz; 1022e1947a5SStefano Zampini } else { 10328f4e0baSStefano Zampini for (i=0;i<matis->sf_nroots;i++) matis->sf_rootdata[i] = d_nnz[i]; 1042e1947a5SStefano Zampini } 1052e1947a5SStefano Zampini if (!o_nnz) { 10628f4e0baSStefano Zampini for (i=0;i<matis->sf_nroots;i++) matis->sf_rootdata[i] += o_nz; 1072e1947a5SStefano Zampini } else { 10828f4e0baSStefano Zampini for (i=0;i<matis->sf_nroots;i++) matis->sf_rootdata[i] += o_nnz[i]; 1092e1947a5SStefano Zampini } 11028f4e0baSStefano Zampini ierr = PetscSFBcastBegin(matis->sf,MPIU_INT,matis->sf_rootdata,matis->sf_leafdata);CHKERRQ(ierr); 11128f4e0baSStefano Zampini ierr = MatGetSize(matis->A,NULL,&nlocalcols);CHKERRQ(ierr); 11228f4e0baSStefano Zampini ierr = MatGetBlockSize(matis->A,&bs);CHKERRQ(ierr); 11328f4e0baSStefano Zampini ierr = PetscSFBcastEnd(matis->sf,MPIU_INT,matis->sf_rootdata,matis->sf_leafdata);CHKERRQ(ierr); 11428f4e0baSStefano Zampini for (i=0;i<matis->sf_nleaves;i++) { 11528f4e0baSStefano Zampini matis->sf_leafdata[i] = PetscMin(matis->sf_leafdata[i],nlocalcols); 1162e1947a5SStefano Zampini } 11728f4e0baSStefano Zampini ierr = MatSeqAIJSetPreallocation(matis->A,0,matis->sf_leafdata);CHKERRQ(ierr); 11828f4e0baSStefano Zampini for (i=0;i<matis->sf_nleaves/bs;i++) { 11928f4e0baSStefano Zampini matis->sf_leafdata[i] = matis->sf_leafdata[i*bs]/bs; 1202e1947a5SStefano Zampini } 12128f4e0baSStefano Zampini ierr = MatSeqBAIJSetPreallocation(matis->A,bs,0,matis->sf_leafdata);CHKERRQ(ierr); 12228f4e0baSStefano Zampini for (i=0;i<matis->sf_nleaves/bs;i++) { 12328f4e0baSStefano Zampini matis->sf_leafdata[i] = matis->sf_leafdata[i]-i; 1242e1947a5SStefano Zampini } 12528f4e0baSStefano Zampini ierr = MatSeqSBAIJSetPreallocation(matis->A,bs,0,matis->sf_leafdata);CHKERRQ(ierr); 1262e1947a5SStefano Zampini PetscFunctionReturn(0); 1272e1947a5SStefano Zampini } 128b4319ba4SBarry Smith 129b4319ba4SBarry Smith #undef __FUNCT__ 1303927de2eSStefano Zampini #define __FUNCT__ "MatISSetMPIXAIJPreallocation_Private" 1313927de2eSStefano Zampini PETSC_EXTERN PetscErrorCode MatISSetMPIXAIJPreallocation_Private(Mat A, Mat B, PetscBool maxreduce) 1323927de2eSStefano Zampini { 1333927de2eSStefano Zampini Mat_IS *matis = (Mat_IS*)(A->data); 1343927de2eSStefano Zampini PetscInt *my_dnz,*my_onz,*dnz,*onz,*mat_ranges,*row_ownership; 135ecf5a873SStefano Zampini const PetscInt *global_indices_r,*global_indices_c; 1363927de2eSStefano Zampini PetscInt i,j,bs,rows,cols; 1373927de2eSStefano Zampini PetscInt lrows,lcols; 1383927de2eSStefano Zampini PetscInt local_rows,local_cols; 1393927de2eSStefano Zampini PetscMPIInt nsubdomains; 1403927de2eSStefano Zampini PetscBool isdense,issbaij; 1413927de2eSStefano Zampini PetscErrorCode ierr; 1423927de2eSStefano Zampini 1433927de2eSStefano Zampini PetscFunctionBegin; 1443927de2eSStefano Zampini ierr = MPI_Comm_size(PetscObjectComm((PetscObject)A),&nsubdomains);CHKERRQ(ierr); 1453927de2eSStefano Zampini ierr = MatGetSize(A,&rows,&cols);CHKERRQ(ierr); 1463927de2eSStefano Zampini ierr = MatGetBlockSize(A,&bs);CHKERRQ(ierr); 1473927de2eSStefano Zampini ierr = MatGetSize(matis->A,&local_rows,&local_cols);CHKERRQ(ierr); 1483927de2eSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)matis->A,MATSEQDENSE,&isdense);CHKERRQ(ierr); 1493927de2eSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)matis->A,MATSEQSBAIJ,&issbaij);CHKERRQ(ierr); 150ecf5a873SStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(A->rmap->mapping,&global_indices_r);CHKERRQ(ierr); 151ecf5a873SStefano Zampini if (A->rmap->mapping != A->cmap->mapping) { 1520ea065fbSStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(A->cmap->mapping,&global_indices_c);CHKERRQ(ierr); 153ecf5a873SStefano Zampini } else { 154ecf5a873SStefano Zampini global_indices_c = global_indices_r; 155ecf5a873SStefano Zampini } 156ecf5a873SStefano Zampini 1573927de2eSStefano Zampini if (issbaij) { 1583927de2eSStefano Zampini ierr = MatGetRowUpperTriangular(matis->A);CHKERRQ(ierr); 1593927de2eSStefano Zampini } 1603927de2eSStefano Zampini /* 161ecf5a873SStefano Zampini An SF reduce is needed to sum up properly on shared rows. 1623927de2eSStefano Zampini Note that generally preallocation is not exact, since it overestimates nonzeros 1633927de2eSStefano Zampini */ 1643927de2eSStefano Zampini if (!matis->sf) { /* setup SF if not yet created and allocate rootdata and leafdata */ 1653927de2eSStefano Zampini ierr = MatISComputeSF_Private(A);CHKERRQ(ierr); 1663927de2eSStefano Zampini } 1673927de2eSStefano Zampini ierr = MatGetLocalSize(A,&lrows,&lcols);CHKERRQ(ierr); 1683927de2eSStefano Zampini ierr = MatPreallocateInitialize(PetscObjectComm((PetscObject)A),lrows,lcols,dnz,onz);CHKERRQ(ierr); 1693927de2eSStefano Zampini /* All processes need to compute entire row ownership */ 1703927de2eSStefano Zampini ierr = PetscMalloc1(rows,&row_ownership);CHKERRQ(ierr); 1713927de2eSStefano Zampini ierr = MatGetOwnershipRanges(A,(const PetscInt**)&mat_ranges);CHKERRQ(ierr); 1723927de2eSStefano Zampini for (i=0;i<nsubdomains;i++) { 1733927de2eSStefano Zampini for (j=mat_ranges[i];j<mat_ranges[i+1];j++) { 1743927de2eSStefano Zampini row_ownership[j] = i; 1753927de2eSStefano Zampini } 1763927de2eSStefano Zampini } 1770ea065fbSStefano Zampini ierr = MatGetOwnershipRangesColumn(A,(const PetscInt**)&mat_ranges);CHKERRQ(ierr); 1783927de2eSStefano Zampini 1793927de2eSStefano Zampini /* 1803927de2eSStefano Zampini my_dnz and my_onz contains exact contribution to preallocation from each local mat 1813927de2eSStefano Zampini then, they will be summed up properly. This way, preallocation is always sufficient 1823927de2eSStefano Zampini */ 1833927de2eSStefano Zampini ierr = PetscCalloc2(local_rows,&my_dnz,local_rows,&my_onz);CHKERRQ(ierr); 1843927de2eSStefano Zampini /* preallocation as a MATAIJ */ 1853927de2eSStefano Zampini if (isdense) { /* special case for dense local matrices */ 1863927de2eSStefano Zampini for (i=0;i<local_rows;i++) { 18712dfadf8SStefano Zampini PetscInt owner = row_ownership[global_indices_r[i]]; 18812dfadf8SStefano Zampini for (j=0;j<local_cols;j++) { 189ecf5a873SStefano Zampini PetscInt index_col = global_indices_c[j]; 1903927de2eSStefano Zampini if (index_col > mat_ranges[owner]-1 && index_col < mat_ranges[owner+1] ) { /* diag block */ 1913927de2eSStefano Zampini my_dnz[i] += 1; 1923927de2eSStefano Zampini } else { /* offdiag block */ 1933927de2eSStefano Zampini my_onz[i] += 1; 1943927de2eSStefano Zampini } 1953927de2eSStefano Zampini } 1963927de2eSStefano Zampini } 197ecf5a873SStefano Zampini } else { /* TODO: this could be optimized using MatGetRowIJ */ 1983927de2eSStefano Zampini for (i=0;i<local_rows;i++) { 1993927de2eSStefano Zampini const PetscInt *cols; 200ecf5a873SStefano Zampini PetscInt ncols,index_row = global_indices_r[i]; 2013927de2eSStefano Zampini ierr = MatGetRow(matis->A,i,&ncols,&cols,NULL);CHKERRQ(ierr); 2023927de2eSStefano Zampini for (j=0;j<ncols;j++) { 2033927de2eSStefano Zampini PetscInt owner = row_ownership[index_row]; 204ecf5a873SStefano Zampini PetscInt index_col = global_indices_c[cols[j]]; 2053927de2eSStefano Zampini if (index_col > mat_ranges[owner]-1 && index_col < mat_ranges[owner+1] ) { /* diag block */ 2063927de2eSStefano Zampini my_dnz[i] += 1; 2073927de2eSStefano Zampini } else { /* offdiag block */ 2083927de2eSStefano Zampini my_onz[i] += 1; 2093927de2eSStefano Zampini } 2103927de2eSStefano Zampini /* same as before, interchanging rows and cols */ 211d9a9e74cSStefano Zampini if (issbaij && index_col != index_row) { 2123927de2eSStefano Zampini owner = row_ownership[index_col]; 2133927de2eSStefano Zampini if (index_row > mat_ranges[owner]-1 && index_row < mat_ranges[owner+1] ) { 214d9a9e74cSStefano Zampini my_dnz[cols[j]] += 1; 2153927de2eSStefano Zampini } else { 216d9a9e74cSStefano Zampini my_onz[cols[j]] += 1; 2173927de2eSStefano Zampini } 2183927de2eSStefano Zampini } 2193927de2eSStefano Zampini } 2203927de2eSStefano Zampini ierr = MatRestoreRow(matis->A,i,&ncols,&cols,NULL);CHKERRQ(ierr); 2213927de2eSStefano Zampini } 2223927de2eSStefano Zampini } 223ecf5a873SStefano Zampini if (global_indices_c != global_indices_r) { 2240ea065fbSStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(A->cmap->mapping,&global_indices_c);CHKERRQ(ierr); 225ecf5a873SStefano Zampini } 2264f619741Sstefano_zampini ierr = ISLocalToGlobalMappingRestoreIndices(A->rmap->mapping,&global_indices_r);CHKERRQ(ierr); 2273927de2eSStefano Zampini ierr = PetscFree(row_ownership);CHKERRQ(ierr); 228ecf5a873SStefano Zampini 229ecf5a873SStefano Zampini /* Reduce my_dnz and my_onz */ 2303927de2eSStefano Zampini if (maxreduce) { 2313927de2eSStefano Zampini ierr = PetscSFReduceBegin(matis->sf,MPIU_INT,my_dnz,dnz,MPI_MAX);CHKERRQ(ierr); 2323927de2eSStefano Zampini ierr = PetscSFReduceEnd(matis->sf,MPIU_INT,my_dnz,dnz,MPI_MAX);CHKERRQ(ierr); 2333927de2eSStefano Zampini ierr = PetscSFReduceBegin(matis->sf,MPIU_INT,my_onz,onz,MPI_MAX);CHKERRQ(ierr); 2343927de2eSStefano Zampini ierr = PetscSFReduceEnd(matis->sf,MPIU_INT,my_onz,onz,MPI_MAX);CHKERRQ(ierr); 2353927de2eSStefano Zampini } else { 2363927de2eSStefano Zampini ierr = PetscSFReduceBegin(matis->sf,MPIU_INT,my_dnz,dnz,MPI_SUM);CHKERRQ(ierr); 2373927de2eSStefano Zampini ierr = PetscSFReduceEnd(matis->sf,MPIU_INT,my_dnz,dnz,MPI_SUM);CHKERRQ(ierr); 2383927de2eSStefano Zampini ierr = PetscSFReduceBegin(matis->sf,MPIU_INT,my_onz,onz,MPI_SUM);CHKERRQ(ierr); 2393927de2eSStefano Zampini ierr = PetscSFReduceEnd(matis->sf,MPIU_INT,my_onz,onz,MPI_SUM);CHKERRQ(ierr); 2403927de2eSStefano Zampini } 2413927de2eSStefano Zampini ierr = PetscFree2(my_dnz,my_onz);CHKERRQ(ierr); 2423927de2eSStefano Zampini 2433927de2eSStefano Zampini /* Resize preallocation if overestimated */ 2443927de2eSStefano Zampini for (i=0;i<lrows;i++) { 2453927de2eSStefano Zampini dnz[i] = PetscMin(dnz[i],lcols); 2463927de2eSStefano Zampini onz[i] = PetscMin(onz[i],cols-lcols); 2473927de2eSStefano Zampini } 2483927de2eSStefano Zampini /* set preallocation */ 2493927de2eSStefano Zampini ierr = MatMPIAIJSetPreallocation(B,0,dnz,0,onz);CHKERRQ(ierr); 2503927de2eSStefano Zampini for (i=0;i<lrows/bs;i++) { 2513927de2eSStefano Zampini dnz[i] = dnz[i*bs]/bs; 2523927de2eSStefano Zampini onz[i] = onz[i*bs]/bs; 2533927de2eSStefano Zampini } 2543927de2eSStefano Zampini ierr = MatMPIBAIJSetPreallocation(B,bs,0,dnz,0,onz);CHKERRQ(ierr); 2553927de2eSStefano Zampini ierr = MatMPISBAIJSetPreallocation(B,bs,0,dnz,0,onz);CHKERRQ(ierr); 2563927de2eSStefano Zampini ierr = MatPreallocateFinalize(dnz,onz);CHKERRQ(ierr); 2573927de2eSStefano Zampini if (issbaij) { 2583927de2eSStefano Zampini ierr = MatRestoreRowUpperTriangular(matis->A);CHKERRQ(ierr); 2593927de2eSStefano Zampini } 2603927de2eSStefano Zampini PetscFunctionReturn(0); 2613927de2eSStefano Zampini } 2623927de2eSStefano Zampini 2633927de2eSStefano Zampini #undef __FUNCT__ 264b7ce53b6SStefano Zampini #define __FUNCT__ "MatISGetMPIXAIJ_IS" 265b7ce53b6SStefano Zampini PetscErrorCode MatISGetMPIXAIJ_IS(Mat mat, MatReuse reuse, Mat *M) 266b7ce53b6SStefano Zampini { 267b7ce53b6SStefano Zampini Mat_IS *matis = (Mat_IS*)(mat->data); 268d9a9e74cSStefano Zampini Mat local_mat; 269b7ce53b6SStefano Zampini /* info on mat */ 2703cfa4ea4SStefano Zampini PetscInt bs,rows,cols,lrows,lcols; 271b7ce53b6SStefano Zampini PetscInt local_rows,local_cols; 272686e3a49SStefano Zampini PetscBool isdense,issbaij,isseqaij; 2737c03b4e8SStefano Zampini PetscMPIInt nsubdomains; 274b7ce53b6SStefano Zampini /* values insertion */ 275b7ce53b6SStefano Zampini PetscScalar *array; 276b7ce53b6SStefano Zampini /* work */ 277b7ce53b6SStefano Zampini PetscErrorCode ierr; 278b7ce53b6SStefano Zampini 279b7ce53b6SStefano Zampini PetscFunctionBegin; 280b7ce53b6SStefano Zampini /* get info from mat */ 2817c03b4e8SStefano Zampini ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&nsubdomains);CHKERRQ(ierr); 2827c03b4e8SStefano Zampini if (nsubdomains == 1) { 2837c03b4e8SStefano Zampini if (reuse == MAT_INITIAL_MATRIX) { 2847c03b4e8SStefano Zampini ierr = MatDuplicate(matis->A,MAT_COPY_VALUES,&(*M));CHKERRQ(ierr); 2857c03b4e8SStefano Zampini } else { 2867c03b4e8SStefano Zampini ierr = MatCopy(matis->A,*M,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 2877c03b4e8SStefano Zampini } 2887c03b4e8SStefano Zampini PetscFunctionReturn(0); 2897c03b4e8SStefano Zampini } 290b7ce53b6SStefano Zampini ierr = MatGetSize(mat,&rows,&cols);CHKERRQ(ierr); 291b7ce53b6SStefano Zampini ierr = MatGetBlockSize(mat,&bs);CHKERRQ(ierr); 2923cfa4ea4SStefano Zampini ierr = MatGetLocalSize(mat,&lrows,&lcols);CHKERRQ(ierr); 293b7ce53b6SStefano Zampini ierr = MatGetSize(matis->A,&local_rows,&local_cols);CHKERRQ(ierr); 294b7ce53b6SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)matis->A,MATSEQDENSE,&isdense);CHKERRQ(ierr); 295686e3a49SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)matis->A,MATSEQAIJ,&isseqaij);CHKERRQ(ierr); 296b7ce53b6SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)matis->A,MATSEQSBAIJ,&issbaij);CHKERRQ(ierr); 297b7ce53b6SStefano Zampini 298b7ce53b6SStefano Zampini if (reuse == MAT_INITIAL_MATRIX) { 299b7ce53b6SStefano Zampini MatType new_mat_type; 3003927de2eSStefano Zampini PetscBool issbaij_red; 301b7ce53b6SStefano Zampini 302b7ce53b6SStefano Zampini /* determining new matrix type */ 303b2566f29SBarry Smith ierr = MPIU_Allreduce(&issbaij,&issbaij_red,1,MPIU_BOOL,MPI_LAND,PetscObjectComm((PetscObject)mat));CHKERRQ(ierr); 304b7ce53b6SStefano Zampini if (issbaij_red) { 305b7ce53b6SStefano Zampini new_mat_type = MATSBAIJ; 306b7ce53b6SStefano Zampini } else { 307b7ce53b6SStefano Zampini if (bs>1) { 308b7ce53b6SStefano Zampini new_mat_type = MATBAIJ; 309b7ce53b6SStefano Zampini } else { 310b7ce53b6SStefano Zampini new_mat_type = MATAIJ; 311b7ce53b6SStefano Zampini } 312b7ce53b6SStefano Zampini } 313b7ce53b6SStefano Zampini 3143927de2eSStefano Zampini ierr = MatCreate(PetscObjectComm((PetscObject)mat),M);CHKERRQ(ierr); 3153cfa4ea4SStefano Zampini ierr = MatSetSizes(*M,lrows,lcols,rows,cols);CHKERRQ(ierr); 3163927de2eSStefano Zampini ierr = MatSetBlockSize(*M,bs);CHKERRQ(ierr); 3173927de2eSStefano Zampini ierr = MatSetType(*M,new_mat_type);CHKERRQ(ierr); 3183927de2eSStefano Zampini ierr = MatISSetMPIXAIJPreallocation_Private(mat,*M,PETSC_FALSE);CHKERRQ(ierr); 319b7ce53b6SStefano Zampini } else { 3203cfa4ea4SStefano Zampini PetscInt mbs,mrows,mcols,mlrows,mlcols; 321b7ce53b6SStefano Zampini /* some checks */ 322b7ce53b6SStefano Zampini ierr = MatGetBlockSize(*M,&mbs);CHKERRQ(ierr); 323b7ce53b6SStefano Zampini ierr = MatGetSize(*M,&mrows,&mcols);CHKERRQ(ierr); 3243cfa4ea4SStefano Zampini ierr = MatGetLocalSize(*M,&mlrows,&mlcols);CHKERRQ(ierr); 3256c4ed002SBarry Smith if (mrows != rows) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot reuse matrix. Wrong number of rows (%d != %d)",rows,mrows); 3266c4ed002SBarry Smith if (mcols != cols) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot reuse matrix. Wrong number of cols (%d != %d)",cols,mcols); 3276c4ed002SBarry Smith if (mlrows != lrows) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot reuse matrix. Wrong number of local rows (%d != %d)",lrows,mlrows); 3286c4ed002SBarry Smith if (mlcols != lcols) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot reuse matrix. Wrong number of local cols (%d != %d)",lcols,mlcols); 3296c4ed002SBarry Smith if (mbs != bs) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot reuse matrix. Wrong block size (%d != %d)",bs,mbs); 330b7ce53b6SStefano Zampini ierr = MatZeroEntries(*M);CHKERRQ(ierr); 331b7ce53b6SStefano Zampini } 332d9a9e74cSStefano Zampini 333d9a9e74cSStefano Zampini if (issbaij) { 334d9a9e74cSStefano Zampini ierr = MatConvert(matis->A,MATSEQBAIJ,MAT_INITIAL_MATRIX,&local_mat);CHKERRQ(ierr); 335d9a9e74cSStefano Zampini } else { 336d9a9e74cSStefano Zampini ierr = PetscObjectReference((PetscObject)matis->A);CHKERRQ(ierr); 337d9a9e74cSStefano Zampini local_mat = matis->A; 338d9a9e74cSStefano Zampini } 339686e3a49SStefano Zampini 340b7ce53b6SStefano Zampini /* Set values */ 341ecf5a873SStefano Zampini ierr = MatSetLocalToGlobalMapping(*M,mat->rmap->mapping,mat->cmap->mapping);CHKERRQ(ierr); 342b7ce53b6SStefano Zampini if (isdense) { /* special case for dense local matrices */ 34365066ba5SStefano Zampini PetscInt i,*dummy; 344ecf5a873SStefano Zampini 34565066ba5SStefano Zampini ierr = PetscMalloc1(PetscMax(local_rows,local_cols),&dummy);CHKERRQ(ierr); 34665066ba5SStefano Zampini for (i=0;i<PetscMax(local_rows,local_cols);i++) dummy[i] = i; 347b7ce53b6SStefano Zampini ierr = MatSetOption(*M,MAT_ROW_ORIENTED,PETSC_FALSE);CHKERRQ(ierr); 348d9a9e74cSStefano Zampini ierr = MatDenseGetArray(local_mat,&array);CHKERRQ(ierr); 34965066ba5SStefano Zampini ierr = MatSetValuesLocal(*M,local_rows,dummy,local_cols,dummy,array,ADD_VALUES);CHKERRQ(ierr); 350d9a9e74cSStefano Zampini ierr = MatDenseRestoreArray(local_mat,&array);CHKERRQ(ierr); 35165066ba5SStefano Zampini ierr = PetscFree(dummy);CHKERRQ(ierr); 352686e3a49SStefano Zampini } else if (isseqaij) { 353ecf5a873SStefano Zampini PetscInt i,nvtxs,*xadj,*adjncy; 354686e3a49SStefano Zampini PetscBool done; 355686e3a49SStefano Zampini 356d9a9e74cSStefano Zampini ierr = MatGetRowIJ(local_mat,0,PETSC_FALSE,PETSC_FALSE,&nvtxs,(const PetscInt**)&xadj,(const PetscInt**)&adjncy,&done);CHKERRQ(ierr); 3576c4ed002SBarry Smith if (!done) SETERRQ1(PetscObjectComm((PetscObject)local_mat),PETSC_ERR_PLIB,"Error in MatRestoreRowIJ called in %s\n",__FUNCT__); 358d9a9e74cSStefano Zampini ierr = MatSeqAIJGetArray(local_mat,&array);CHKERRQ(ierr); 359686e3a49SStefano Zampini for (i=0;i<nvtxs;i++) { 360ecf5a873SStefano Zampini ierr = MatSetValuesLocal(*M,1,&i,xadj[i+1]-xadj[i],adjncy+xadj[i],array+xadj[i],ADD_VALUES);CHKERRQ(ierr); 361686e3a49SStefano Zampini } 362d9a9e74cSStefano Zampini ierr = MatRestoreRowIJ(local_mat,0,PETSC_FALSE,PETSC_FALSE,&nvtxs,(const PetscInt**)&xadj,(const PetscInt**)&adjncy,&done);CHKERRQ(ierr); 3636c4ed002SBarry Smith if (!done) SETERRQ1(PetscObjectComm((PetscObject)local_mat),PETSC_ERR_PLIB,"Error in MatRestoreRowIJ called in %s\n",__FUNCT__); 364d9a9e74cSStefano Zampini ierr = MatSeqAIJRestoreArray(local_mat,&array);CHKERRQ(ierr); 365686e3a49SStefano Zampini } else { /* very basic values insertion for all other matrix types */ 366ecf5a873SStefano Zampini PetscInt i; 367c0962df8SStefano Zampini 368686e3a49SStefano Zampini for (i=0;i<local_rows;i++) { 369686e3a49SStefano Zampini PetscInt j; 370ecf5a873SStefano Zampini const PetscInt *local_indices_cols; 371686e3a49SStefano Zampini 372ecf5a873SStefano Zampini ierr = MatGetRow(local_mat,i,&j,&local_indices_cols,(const PetscScalar**)&array);CHKERRQ(ierr); 373ecf5a873SStefano Zampini ierr = MatSetValuesLocal(*M,1,&i,j,local_indices_cols,array,ADD_VALUES);CHKERRQ(ierr); 374ecf5a873SStefano Zampini ierr = MatRestoreRow(local_mat,i,&j,&local_indices_cols,(const PetscScalar**)&array);CHKERRQ(ierr); 375686e3a49SStefano Zampini } 376b7ce53b6SStefano Zampini } 377b7ce53b6SStefano Zampini ierr = MatAssemblyBegin(*M,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 378d9a9e74cSStefano Zampini ierr = MatDestroy(&local_mat);CHKERRQ(ierr); 379b7ce53b6SStefano Zampini ierr = MatAssemblyEnd(*M,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 380b7ce53b6SStefano Zampini if (isdense) { 381b7ce53b6SStefano Zampini ierr = MatSetOption(*M,MAT_ROW_ORIENTED,PETSC_TRUE);CHKERRQ(ierr); 382b7ce53b6SStefano Zampini } 383b7ce53b6SStefano Zampini PetscFunctionReturn(0); 384b7ce53b6SStefano Zampini } 385b7ce53b6SStefano Zampini 386b7ce53b6SStefano Zampini #undef __FUNCT__ 387b7ce53b6SStefano Zampini #define __FUNCT__ "MatISGetMPIXAIJ" 388b7ce53b6SStefano Zampini /*@ 389b7ce53b6SStefano Zampini MatISGetMPIXAIJ - Converts MATIS matrix into a parallel AIJ format 390b7ce53b6SStefano Zampini 391b7ce53b6SStefano Zampini Input Parameter: 392b7ce53b6SStefano Zampini . mat - the matrix (should be of type MATIS) 393b7ce53b6SStefano Zampini . reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 394b7ce53b6SStefano Zampini 395b7ce53b6SStefano Zampini Output Parameter: 396b7ce53b6SStefano Zampini . newmat - the matrix in AIJ format 397b7ce53b6SStefano Zampini 398b7ce53b6SStefano Zampini Level: developer 399b7ce53b6SStefano Zampini 400eb82efa4SStefano Zampini Notes: mat and *newmat cannot be the same object when MAT_REUSE_MATRIX is requested. 401b7ce53b6SStefano Zampini 402b7ce53b6SStefano Zampini .seealso: MATIS 403b7ce53b6SStefano Zampini @*/ 404b7ce53b6SStefano Zampini PetscErrorCode MatISGetMPIXAIJ(Mat mat, MatReuse reuse, Mat *newmat) 405b7ce53b6SStefano Zampini { 406b7ce53b6SStefano Zampini PetscErrorCode ierr; 407b7ce53b6SStefano Zampini 408b7ce53b6SStefano Zampini PetscFunctionBegin; 409b7ce53b6SStefano Zampini PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 410b7ce53b6SStefano Zampini PetscValidLogicalCollectiveEnum(mat,reuse,2); 411b7ce53b6SStefano Zampini PetscValidPointer(newmat,3); 412b7ce53b6SStefano Zampini if (reuse != MAT_INITIAL_MATRIX) { 413b7ce53b6SStefano Zampini PetscValidHeaderSpecific(*newmat,MAT_CLASSID,3); 414b7ce53b6SStefano Zampini PetscCheckSameComm(mat,1,*newmat,3); 4156c4ed002SBarry Smith if (mat == *newmat) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot reuse the same matrix"); 416b7ce53b6SStefano Zampini } 417b7ce53b6SStefano Zampini ierr = PetscUseMethod(mat,"MatISGetMPIXAIJ_C",(Mat,MatReuse,Mat*),(mat,reuse,newmat));CHKERRQ(ierr); 418b7ce53b6SStefano Zampini PetscFunctionReturn(0); 419b7ce53b6SStefano Zampini } 420b7ce53b6SStefano Zampini 421b7ce53b6SStefano Zampini #undef __FUNCT__ 422ad6194a2SStefano Zampini #define __FUNCT__ "MatDuplicate_IS" 423ad6194a2SStefano Zampini PetscErrorCode MatDuplicate_IS(Mat mat,MatDuplicateOption op,Mat *newmat) 424ad6194a2SStefano Zampini { 425ad6194a2SStefano Zampini PetscErrorCode ierr; 426ad6194a2SStefano Zampini Mat_IS *matis = (Mat_IS*)(mat->data); 427ad6194a2SStefano Zampini PetscInt bs,m,n,M,N; 428ad6194a2SStefano Zampini Mat B,localmat; 429ad6194a2SStefano Zampini 430ad6194a2SStefano Zampini PetscFunctionBegin; 431ad6194a2SStefano Zampini ierr = MatGetBlockSize(mat,&bs);CHKERRQ(ierr); 432ad6194a2SStefano Zampini ierr = MatGetSize(mat,&M,&N);CHKERRQ(ierr); 433ad6194a2SStefano Zampini ierr = MatGetLocalSize(mat,&m,&n);CHKERRQ(ierr); 434e176bc59SStefano Zampini ierr = MatCreateIS(PetscObjectComm((PetscObject)mat),bs,m,n,M,N,mat->rmap->mapping,mat->cmap->mapping,&B);CHKERRQ(ierr); 435ad6194a2SStefano Zampini ierr = MatDuplicate(matis->A,op,&localmat);CHKERRQ(ierr); 436ad6194a2SStefano Zampini ierr = MatISSetLocalMat(B,localmat);CHKERRQ(ierr); 437b3317aa8SStefano Zampini ierr = MatDestroy(&localmat);CHKERRQ(ierr); 438ad6194a2SStefano Zampini ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 439ad6194a2SStefano Zampini ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 440ad6194a2SStefano Zampini *newmat = B; 441ad6194a2SStefano Zampini PetscFunctionReturn(0); 442ad6194a2SStefano Zampini } 443ad6194a2SStefano Zampini 444ad6194a2SStefano Zampini #undef __FUNCT__ 44569796d55SStefano Zampini #define __FUNCT__ "MatIsHermitian_IS" 44669796d55SStefano Zampini PetscErrorCode MatIsHermitian_IS(Mat A,PetscReal tol,PetscBool *flg) 44769796d55SStefano Zampini { 44869796d55SStefano Zampini PetscErrorCode ierr; 44969796d55SStefano Zampini Mat_IS *matis = (Mat_IS*)A->data; 45069796d55SStefano Zampini PetscBool local_sym; 45169796d55SStefano Zampini 45269796d55SStefano Zampini PetscFunctionBegin; 45369796d55SStefano Zampini ierr = MatIsHermitian(matis->A,tol,&local_sym);CHKERRQ(ierr); 454b2566f29SBarry Smith ierr = MPIU_Allreduce(&local_sym,flg,1,MPIU_BOOL,MPI_LAND,PetscObjectComm((PetscObject)A));CHKERRQ(ierr); 45569796d55SStefano Zampini PetscFunctionReturn(0); 45669796d55SStefano Zampini } 45769796d55SStefano Zampini 45869796d55SStefano Zampini #undef __FUNCT__ 45969796d55SStefano Zampini #define __FUNCT__ "MatIsSymmetric_IS" 46069796d55SStefano Zampini PetscErrorCode MatIsSymmetric_IS(Mat A,PetscReal tol,PetscBool *flg) 46169796d55SStefano Zampini { 46269796d55SStefano Zampini PetscErrorCode ierr; 46369796d55SStefano Zampini Mat_IS *matis = (Mat_IS*)A->data; 46469796d55SStefano Zampini PetscBool local_sym; 46569796d55SStefano Zampini 46669796d55SStefano Zampini PetscFunctionBegin; 46769796d55SStefano Zampini ierr = MatIsSymmetric(matis->A,tol,&local_sym);CHKERRQ(ierr); 468b2566f29SBarry Smith ierr = MPIU_Allreduce(&local_sym,flg,1,MPIU_BOOL,MPI_LAND,PetscObjectComm((PetscObject)A));CHKERRQ(ierr); 46969796d55SStefano Zampini PetscFunctionReturn(0); 47069796d55SStefano Zampini } 47169796d55SStefano Zampini 47269796d55SStefano Zampini #undef __FUNCT__ 473b4319ba4SBarry Smith #define __FUNCT__ "MatDestroy_IS" 474dfbe8321SBarry Smith PetscErrorCode MatDestroy_IS(Mat A) 475b4319ba4SBarry Smith { 476dfbe8321SBarry Smith PetscErrorCode ierr; 477b4319ba4SBarry Smith Mat_IS *b = (Mat_IS*)A->data; 478b4319ba4SBarry Smith 479b4319ba4SBarry Smith PetscFunctionBegin; 4806bf464f9SBarry Smith ierr = MatDestroy(&b->A);CHKERRQ(ierr); 481e176bc59SStefano Zampini ierr = VecScatterDestroy(&b->cctx);CHKERRQ(ierr); 482e176bc59SStefano Zampini ierr = VecScatterDestroy(&b->rctx);CHKERRQ(ierr); 4836bf464f9SBarry Smith ierr = VecDestroy(&b->x);CHKERRQ(ierr); 4846bf464f9SBarry Smith ierr = VecDestroy(&b->y);CHKERRQ(ierr); 48528f4e0baSStefano Zampini ierr = PetscSFDestroy(&b->sf);CHKERRQ(ierr); 48628f4e0baSStefano Zampini ierr = PetscFree2(b->sf_rootdata,b->sf_leafdata);CHKERRQ(ierr); 487bf0cc555SLisandro Dalcin ierr = PetscFree(A->data);CHKERRQ(ierr); 488dbd8c25aSHong Zhang ierr = PetscObjectChangeTypeName((PetscObject)A,0);CHKERRQ(ierr); 489bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatISGetLocalMat_C",NULL);CHKERRQ(ierr); 490b7ce53b6SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatISSetLocalMat_C",NULL);CHKERRQ(ierr); 491b7ce53b6SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatISGetMPIXAIJ_C",NULL);CHKERRQ(ierr); 4922e1947a5SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatISSetPreallocation_C",NULL);CHKERRQ(ierr); 493b4319ba4SBarry Smith PetscFunctionReturn(0); 494b4319ba4SBarry Smith } 495b4319ba4SBarry Smith 496b4319ba4SBarry Smith #undef __FUNCT__ 497b4319ba4SBarry Smith #define __FUNCT__ "MatMult_IS" 498dfbe8321SBarry Smith PetscErrorCode MatMult_IS(Mat A,Vec x,Vec y) 499b4319ba4SBarry Smith { 500dfbe8321SBarry Smith PetscErrorCode ierr; 501b4319ba4SBarry Smith Mat_IS *is = (Mat_IS*)A->data; 502b4319ba4SBarry Smith PetscScalar zero = 0.0; 503b4319ba4SBarry Smith 504b4319ba4SBarry Smith PetscFunctionBegin; 505b4319ba4SBarry Smith /* scatter the global vector x into the local work vector */ 506e176bc59SStefano Zampini ierr = VecScatterBegin(is->cctx,x,is->x,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 507e176bc59SStefano Zampini ierr = VecScatterEnd(is->cctx,x,is->x,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 508b4319ba4SBarry Smith 509b4319ba4SBarry Smith /* multiply the local matrix */ 510b4319ba4SBarry Smith ierr = MatMult(is->A,is->x,is->y);CHKERRQ(ierr); 511b4319ba4SBarry Smith 512b4319ba4SBarry Smith /* scatter product back into global memory */ 5132dcb1b2aSMatthew Knepley ierr = VecSet(y,zero);CHKERRQ(ierr); 514e176bc59SStefano Zampini ierr = VecScatterBegin(is->rctx,is->y,y,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 515e176bc59SStefano Zampini ierr = VecScatterEnd(is->rctx,is->y,y,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 516b4319ba4SBarry Smith PetscFunctionReturn(0); 517b4319ba4SBarry Smith } 518b4319ba4SBarry Smith 519b4319ba4SBarry Smith #undef __FUNCT__ 5202e74eeadSLisandro Dalcin #define __FUNCT__ "MatMultAdd_IS" 521b7ce53b6SStefano Zampini PetscErrorCode MatMultAdd_IS(Mat A,Vec v1,Vec v2,Vec v3) 5222e74eeadSLisandro Dalcin { 523650997f4SStefano Zampini Vec temp_vec; 5242e74eeadSLisandro Dalcin PetscErrorCode ierr; 5252e74eeadSLisandro Dalcin 5262e74eeadSLisandro Dalcin PetscFunctionBegin; /* v3 = v2 + A * v1.*/ 527650997f4SStefano Zampini if (v3 != v2) { 528650997f4SStefano Zampini ierr = MatMult(A,v1,v3);CHKERRQ(ierr); 529650997f4SStefano Zampini ierr = VecAXPY(v3,1.0,v2);CHKERRQ(ierr); 530650997f4SStefano Zampini } else { 531650997f4SStefano Zampini ierr = VecDuplicate(v2,&temp_vec);CHKERRQ(ierr); 532650997f4SStefano Zampini ierr = MatMult(A,v1,temp_vec);CHKERRQ(ierr); 533650997f4SStefano Zampini ierr = VecAXPY(temp_vec,1.0,v2);CHKERRQ(ierr); 534650997f4SStefano Zampini ierr = VecCopy(temp_vec,v3);CHKERRQ(ierr); 535650997f4SStefano Zampini ierr = VecDestroy(&temp_vec);CHKERRQ(ierr); 536650997f4SStefano Zampini } 5372e74eeadSLisandro Dalcin PetscFunctionReturn(0); 5382e74eeadSLisandro Dalcin } 5392e74eeadSLisandro Dalcin 5402e74eeadSLisandro Dalcin #undef __FUNCT__ 5412e74eeadSLisandro Dalcin #define __FUNCT__ "MatMultTranspose_IS" 542e176bc59SStefano Zampini PetscErrorCode MatMultTranspose_IS(Mat A,Vec y,Vec x) 5432e74eeadSLisandro Dalcin { 5442e74eeadSLisandro Dalcin Mat_IS *is = (Mat_IS*)A->data; 5452e74eeadSLisandro Dalcin PetscErrorCode ierr; 5462e74eeadSLisandro Dalcin 547e176bc59SStefano Zampini PetscFunctionBegin; 5482e74eeadSLisandro Dalcin /* scatter the global vector x into the local work vector */ 549e176bc59SStefano Zampini ierr = VecScatterBegin(is->rctx,y,is->y,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 550e176bc59SStefano Zampini ierr = VecScatterEnd(is->rctx,y,is->y,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 5512e74eeadSLisandro Dalcin 5522e74eeadSLisandro Dalcin /* multiply the local matrix */ 553e176bc59SStefano Zampini ierr = MatMultTranspose(is->A,is->y,is->x);CHKERRQ(ierr); 5542e74eeadSLisandro Dalcin 5552e74eeadSLisandro Dalcin /* scatter product back into global vector */ 556e176bc59SStefano Zampini ierr = VecSet(x,0);CHKERRQ(ierr); 557e176bc59SStefano Zampini ierr = VecScatterBegin(is->cctx,is->x,x,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 558e176bc59SStefano Zampini ierr = VecScatterEnd(is->cctx,is->x,x,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 5592e74eeadSLisandro Dalcin PetscFunctionReturn(0); 5602e74eeadSLisandro Dalcin } 5612e74eeadSLisandro Dalcin 5622e74eeadSLisandro Dalcin #undef __FUNCT__ 5632e74eeadSLisandro Dalcin #define __FUNCT__ "MatMultTransposeAdd_IS" 5642e74eeadSLisandro Dalcin PetscErrorCode MatMultTransposeAdd_IS(Mat A,Vec v1,Vec v2,Vec v3) 5652e74eeadSLisandro Dalcin { 566650997f4SStefano Zampini Vec temp_vec; 5672e74eeadSLisandro Dalcin PetscErrorCode ierr; 5682e74eeadSLisandro Dalcin 5692e74eeadSLisandro Dalcin PetscFunctionBegin; /* v3 = v2 + A' * v1.*/ 570650997f4SStefano Zampini if (v3 != v2) { 571650997f4SStefano Zampini ierr = MatMultTranspose(A,v1,v3);CHKERRQ(ierr); 572650997f4SStefano Zampini ierr = VecAXPY(v3,1.0,v2);CHKERRQ(ierr); 573650997f4SStefano Zampini } else { 574650997f4SStefano Zampini ierr = VecDuplicate(v2,&temp_vec);CHKERRQ(ierr); 575650997f4SStefano Zampini ierr = MatMultTranspose(A,v1,temp_vec);CHKERRQ(ierr); 576650997f4SStefano Zampini ierr = VecAXPY(temp_vec,1.0,v2);CHKERRQ(ierr); 577650997f4SStefano Zampini ierr = VecCopy(temp_vec,v3);CHKERRQ(ierr); 578650997f4SStefano Zampini ierr = VecDestroy(&temp_vec);CHKERRQ(ierr); 579650997f4SStefano Zampini } 5802e74eeadSLisandro Dalcin PetscFunctionReturn(0); 5812e74eeadSLisandro Dalcin } 5822e74eeadSLisandro Dalcin 5832e74eeadSLisandro Dalcin #undef __FUNCT__ 584b4319ba4SBarry Smith #define __FUNCT__ "MatView_IS" 585dfbe8321SBarry Smith PetscErrorCode MatView_IS(Mat A,PetscViewer viewer) 586b4319ba4SBarry Smith { 587b4319ba4SBarry Smith Mat_IS *a = (Mat_IS*)A->data; 588dfbe8321SBarry Smith PetscErrorCode ierr; 589b4319ba4SBarry Smith PetscViewer sviewer; 590b4319ba4SBarry Smith 591b4319ba4SBarry Smith PetscFunctionBegin; 5923f08860eSBarry Smith ierr = PetscViewerGetSubViewer(viewer,PETSC_COMM_SELF,&sviewer);CHKERRQ(ierr); 593b4319ba4SBarry Smith ierr = MatView(a->A,sviewer);CHKERRQ(ierr); 5943f08860eSBarry Smith ierr = PetscViewerRestoreSubViewer(viewer,PETSC_COMM_SELF,&sviewer);CHKERRQ(ierr); 595b4319ba4SBarry Smith PetscFunctionReturn(0); 596b4319ba4SBarry Smith } 597b4319ba4SBarry Smith 598b4319ba4SBarry Smith #undef __FUNCT__ 599b4319ba4SBarry Smith #define __FUNCT__ "MatSetLocalToGlobalMapping_IS" 600784ac674SJed Brown PetscErrorCode MatSetLocalToGlobalMapping_IS(Mat A,ISLocalToGlobalMapping rmapping,ISLocalToGlobalMapping cmapping) 601b4319ba4SBarry Smith { 602dfbe8321SBarry Smith PetscErrorCode ierr; 603e176bc59SStefano Zampini PetscInt nr,rbs,nc,cbs; 604b4319ba4SBarry Smith Mat_IS *is = (Mat_IS*)A->data; 605b4319ba4SBarry Smith IS from,to; 606e176bc59SStefano Zampini Vec cglobal,rglobal; 607b4319ba4SBarry Smith 608b4319ba4SBarry Smith PetscFunctionBegin; 609784ac674SJed Brown PetscCheckSameComm(A,1,rmapping,2); 610e176bc59SStefano Zampini PetscCheckSameComm(A,1,cmapping,3); 6113bbff08aSStefano Zampini /* Destroy any previous data */ 61270cf5478SStefano Zampini ierr = VecDestroy(&is->x);CHKERRQ(ierr); 61370cf5478SStefano Zampini ierr = VecDestroy(&is->y);CHKERRQ(ierr); 614e176bc59SStefano Zampini ierr = VecScatterDestroy(&is->rctx);CHKERRQ(ierr); 615e176bc59SStefano Zampini ierr = VecScatterDestroy(&is->cctx);CHKERRQ(ierr); 6161c47cb0fSStefano Zampini ierr = MatDestroy(&is->A);CHKERRQ(ierr); 61728f4e0baSStefano Zampini ierr = PetscSFDestroy(&is->sf);CHKERRQ(ierr); 61828f4e0baSStefano Zampini ierr = PetscFree2(is->sf_rootdata,is->sf_leafdata);CHKERRQ(ierr); 6193bbff08aSStefano Zampini 6203bbff08aSStefano Zampini /* Setup Layout and set local to global maps */ 621fc27028aSStefano Zampini ierr = PetscLayoutSetUp(A->rmap);CHKERRQ(ierr); 622fc27028aSStefano Zampini ierr = PetscLayoutSetUp(A->cmap);CHKERRQ(ierr); 623fa7f1dd8SStefano Zampini ierr = PetscLayoutSetISLocalToGlobalMapping(A->rmap,rmapping);CHKERRQ(ierr); 624fa7f1dd8SStefano Zampini ierr = PetscLayoutSetISLocalToGlobalMapping(A->cmap,cmapping);CHKERRQ(ierr); 625b4319ba4SBarry Smith 626b4319ba4SBarry Smith /* Create the local matrix A */ 627e176bc59SStefano Zampini ierr = ISLocalToGlobalMappingGetSize(rmapping,&nr);CHKERRQ(ierr); 628e176bc59SStefano Zampini ierr = ISLocalToGlobalMappingGetBlockSize(rmapping,&rbs);CHKERRQ(ierr); 629e176bc59SStefano Zampini ierr = ISLocalToGlobalMappingGetSize(cmapping,&nc);CHKERRQ(ierr); 630e176bc59SStefano Zampini ierr = ISLocalToGlobalMappingGetBlockSize(cmapping,&cbs);CHKERRQ(ierr); 631f69a0ea3SMatthew Knepley ierr = MatCreate(PETSC_COMM_SELF,&is->A);CHKERRQ(ierr); 632e176bc59SStefano Zampini ierr = MatSetType(is->A,MATAIJ);CHKERRQ(ierr); 633e176bc59SStefano Zampini ierr = MatSetSizes(is->A,nr,nc,nr,nc);CHKERRQ(ierr); 634e176bc59SStefano Zampini ierr = MatSetBlockSizes(is->A,rbs,cbs);CHKERRQ(ierr); 635ff130e51SJed Brown ierr = MatSetOptionsPrefix(is->A,((PetscObject)A)->prefix);CHKERRQ(ierr); 636ff130e51SJed Brown ierr = MatAppendOptionsPrefix(is->A,"is_");CHKERRQ(ierr); 637b4319ba4SBarry Smith ierr = MatSetFromOptions(is->A);CHKERRQ(ierr); 638*c77832edSStefano Zampini ierr = PetscLayoutSetUp(is->A->rmap);CHKERRQ(ierr); 639*c77832edSStefano Zampini ierr = PetscLayoutSetUp(is->A->cmap);CHKERRQ(ierr); 640b4319ba4SBarry Smith 641b4319ba4SBarry Smith /* Create the local work vectors */ 6423bbff08aSStefano Zampini ierr = MatCreateVecs(is->A,&is->x,&is->y);CHKERRQ(ierr); 643b4319ba4SBarry Smith 644e176bc59SStefano Zampini /* setup the global to local scatters */ 645e176bc59SStefano Zampini ierr = MatCreateVecs(A,&cglobal,&rglobal);CHKERRQ(ierr); 646e176bc59SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,nr,0,1,&to);CHKERRQ(ierr); 647784ac674SJed Brown ierr = ISLocalToGlobalMappingApplyIS(rmapping,to,&from);CHKERRQ(ierr); 648e176bc59SStefano Zampini ierr = VecScatterCreate(rglobal,from,is->y,to,&is->rctx);CHKERRQ(ierr); 649e176bc59SStefano Zampini if (rmapping != cmapping) { 650e176bc59SStefano Zampini ierr = ISDestroy(&to);CHKERRQ(ierr); 651e176bc59SStefano Zampini ierr = ISDestroy(&from);CHKERRQ(ierr); 652e176bc59SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,nc,0,1,&to);CHKERRQ(ierr); 653e176bc59SStefano Zampini ierr = ISLocalToGlobalMappingApplyIS(cmapping,to,&from);CHKERRQ(ierr); 654e176bc59SStefano Zampini ierr = VecScatterCreate(cglobal,from,is->x,to,&is->cctx);CHKERRQ(ierr); 655e176bc59SStefano Zampini } else { 656e176bc59SStefano Zampini ierr = PetscObjectReference((PetscObject)is->rctx);CHKERRQ(ierr); 657e176bc59SStefano Zampini is->cctx = is->rctx; 658e176bc59SStefano Zampini } 659e176bc59SStefano Zampini ierr = VecDestroy(&rglobal);CHKERRQ(ierr); 660e176bc59SStefano Zampini ierr = VecDestroy(&cglobal);CHKERRQ(ierr); 6616bf464f9SBarry Smith ierr = ISDestroy(&to);CHKERRQ(ierr); 6626bf464f9SBarry Smith ierr = ISDestroy(&from);CHKERRQ(ierr); 663b4319ba4SBarry Smith PetscFunctionReturn(0); 664b4319ba4SBarry Smith } 665b4319ba4SBarry Smith 6662e74eeadSLisandro Dalcin #undef __FUNCT__ 6672e74eeadSLisandro Dalcin #define __FUNCT__ "MatSetValues_IS" 6682e74eeadSLisandro Dalcin PetscErrorCode MatSetValues_IS(Mat mat, PetscInt m,const PetscInt *rows, PetscInt n,const PetscInt *cols, const PetscScalar *values, InsertMode addv) 6692e74eeadSLisandro Dalcin { 6702e74eeadSLisandro Dalcin Mat_IS *is = (Mat_IS*)mat->data; 6712e74eeadSLisandro Dalcin PetscInt rows_l[2048],cols_l[2048]; 6722e74eeadSLisandro Dalcin PetscErrorCode ierr; 6732e74eeadSLisandro Dalcin 6742e74eeadSLisandro Dalcin PetscFunctionBegin; 6752e74eeadSLisandro Dalcin #if defined(PETSC_USE_DEBUG) 676f23aa3ddSBarry 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); 6772e74eeadSLisandro Dalcin #endif 6783bbff08aSStefano Zampini ierr = ISG2LMapApply(mat->rmap->mapping,m,rows,rows_l);CHKERRQ(ierr); 6793bbff08aSStefano Zampini ierr = ISG2LMapApply(mat->cmap->mapping,n,cols,cols_l);CHKERRQ(ierr); 6802e74eeadSLisandro Dalcin ierr = MatSetValues(is->A,m,rows_l,n,cols_l,values,addv);CHKERRQ(ierr); 6812e74eeadSLisandro Dalcin PetscFunctionReturn(0); 6822e74eeadSLisandro Dalcin } 6832e74eeadSLisandro Dalcin 684b4319ba4SBarry Smith #undef __FUNCT__ 685b4319ba4SBarry Smith #define __FUNCT__ "MatSetValuesLocal_IS" 68613f74950SBarry Smith PetscErrorCode MatSetValuesLocal_IS(Mat A,PetscInt m,const PetscInt *rows, PetscInt n,const PetscInt *cols,const PetscScalar *values,InsertMode addv) 687b4319ba4SBarry Smith { 688dfbe8321SBarry Smith PetscErrorCode ierr; 689b4319ba4SBarry Smith Mat_IS *is = (Mat_IS*)A->data; 690b4319ba4SBarry Smith 691b4319ba4SBarry Smith PetscFunctionBegin; 692b4319ba4SBarry Smith ierr = MatSetValues(is->A,m,rows,n,cols,values,addv);CHKERRQ(ierr); 693b4319ba4SBarry Smith PetscFunctionReturn(0); 694b4319ba4SBarry Smith } 695b4319ba4SBarry Smith 696b4319ba4SBarry Smith #undef __FUNCT__ 697f0006bf2SLisandro Dalcin #define __FUNCT__ "MatSetValuesBlockedLocal_IS" 698f0006bf2SLisandro Dalcin PetscErrorCode MatSetValuesBlockedLocal_IS(Mat A,PetscInt m,const PetscInt *rows, PetscInt n,const PetscInt *cols,const PetscScalar *values,InsertMode addv) 699f0006bf2SLisandro Dalcin { 700f0006bf2SLisandro Dalcin PetscErrorCode ierr; 701f0006bf2SLisandro Dalcin Mat_IS *is = (Mat_IS*)A->data; 702f0006bf2SLisandro Dalcin 703f0006bf2SLisandro Dalcin PetscFunctionBegin; 704f0006bf2SLisandro Dalcin ierr = MatSetValuesBlocked(is->A,m,rows,n,cols,values,addv);CHKERRQ(ierr); 705f0006bf2SLisandro Dalcin PetscFunctionReturn(0); 706f0006bf2SLisandro Dalcin } 707f0006bf2SLisandro Dalcin 708f0006bf2SLisandro Dalcin #undef __FUNCT__ 7092e74eeadSLisandro Dalcin #define __FUNCT__ "MatZeroRows_IS" 7102b40b63fSBarry Smith PetscErrorCode MatZeroRows_IS(Mat A,PetscInt n,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 7112e74eeadSLisandro Dalcin { 7120298fd71SBarry Smith PetscInt n_l = 0, *rows_l = NULL; 7132e74eeadSLisandro Dalcin PetscErrorCode ierr; 7142e74eeadSLisandro Dalcin 7152e74eeadSLisandro Dalcin PetscFunctionBegin; 716ce94432eSBarry Smith if (x && b) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"No support"); 7172e74eeadSLisandro Dalcin if (n) { 718785e854fSJed Brown ierr = PetscMalloc1(n,&rows_l);CHKERRQ(ierr); 7193bbff08aSStefano Zampini ierr = ISGlobalToLocalMappingApply(A->rmap->mapping,IS_GTOLM_DROP,n,rows,&n_l,rows_l);CHKERRQ(ierr); 7202e74eeadSLisandro Dalcin } 7212b40b63fSBarry Smith ierr = MatZeroRowsLocal(A,n_l,rows_l,diag,x,b);CHKERRQ(ierr); 722c31cb41cSBarry Smith ierr = PetscFree(rows_l);CHKERRQ(ierr); 7232e74eeadSLisandro Dalcin PetscFunctionReturn(0); 7242e74eeadSLisandro Dalcin } 7252e74eeadSLisandro Dalcin 7262e74eeadSLisandro Dalcin #undef __FUNCT__ 727b4319ba4SBarry Smith #define __FUNCT__ "MatZeroRowsLocal_IS" 7282b40b63fSBarry Smith PetscErrorCode MatZeroRowsLocal_IS(Mat A,PetscInt n,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 729b4319ba4SBarry Smith { 730b4319ba4SBarry Smith Mat_IS *is = (Mat_IS*)A->data; 731dfbe8321SBarry Smith PetscErrorCode ierr; 732f4df32b1SMatthew Knepley PetscInt i; 733b4319ba4SBarry Smith PetscScalar *array; 734b4319ba4SBarry Smith 735b4319ba4SBarry Smith PetscFunctionBegin; 736ce94432eSBarry Smith if (x && b) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"No support"); 737b4319ba4SBarry Smith { 738b4319ba4SBarry Smith /* 739b4319ba4SBarry Smith Set up is->x as a "counting vector". This is in order to MatMult_IS 740b4319ba4SBarry Smith work properly in the interface nodes. 741b4319ba4SBarry Smith */ 742b4319ba4SBarry Smith Vec counter; 743e176bc59SStefano Zampini ierr = MatCreateVecs(A,NULL,&counter);CHKERRQ(ierr); 744e176bc59SStefano Zampini ierr = VecSet(counter,0.);CHKERRQ(ierr); 745e176bc59SStefano Zampini ierr = VecSet(is->y,1.);CHKERRQ(ierr); 746e176bc59SStefano Zampini ierr = VecScatterBegin(is->rctx,is->y,counter,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 747e176bc59SStefano Zampini ierr = VecScatterEnd(is->rctx,is->y,counter,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 748e176bc59SStefano Zampini ierr = VecScatterBegin(is->rctx,counter,is->y,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 749e176bc59SStefano Zampini ierr = VecScatterEnd(is->rctx,counter,is->y,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 7506bf464f9SBarry Smith ierr = VecDestroy(&counter);CHKERRQ(ierr); 751b4319ba4SBarry Smith } 752958c9bccSBarry Smith if (!n) { 753b4319ba4SBarry Smith is->pure_neumann = PETSC_TRUE; 754b4319ba4SBarry Smith } else { 755b4319ba4SBarry Smith is->pure_neumann = PETSC_FALSE; 7562205254eSKarl Rupp 757e176bc59SStefano Zampini ierr = VecGetArray(is->y,&array);CHKERRQ(ierr); 7582b40b63fSBarry Smith ierr = MatZeroRows(is->A,n,rows,diag,0,0);CHKERRQ(ierr); 759b4319ba4SBarry Smith for (i=0; i<n; i++) { 760f4df32b1SMatthew Knepley ierr = MatSetValue(is->A,rows[i],rows[i],diag/(array[rows[i]]),INSERT_VALUES);CHKERRQ(ierr); 761b4319ba4SBarry Smith } 762b4319ba4SBarry Smith ierr = MatAssemblyBegin(is->A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 763b4319ba4SBarry Smith ierr = MatAssemblyEnd(is->A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 764e176bc59SStefano Zampini ierr = VecRestoreArray(is->y,&array);CHKERRQ(ierr); 765b4319ba4SBarry Smith } 766b4319ba4SBarry Smith PetscFunctionReturn(0); 767b4319ba4SBarry Smith } 768b4319ba4SBarry Smith 769b4319ba4SBarry Smith #undef __FUNCT__ 770b4319ba4SBarry Smith #define __FUNCT__ "MatAssemblyBegin_IS" 771dfbe8321SBarry Smith PetscErrorCode MatAssemblyBegin_IS(Mat A,MatAssemblyType type) 772b4319ba4SBarry Smith { 773b4319ba4SBarry Smith Mat_IS *is = (Mat_IS*)A->data; 774dfbe8321SBarry Smith PetscErrorCode ierr; 775b4319ba4SBarry Smith 776b4319ba4SBarry Smith PetscFunctionBegin; 777b4319ba4SBarry Smith ierr = MatAssemblyBegin(is->A,type);CHKERRQ(ierr); 778b4319ba4SBarry Smith PetscFunctionReturn(0); 779b4319ba4SBarry Smith } 780b4319ba4SBarry Smith 781b4319ba4SBarry Smith #undef __FUNCT__ 782b4319ba4SBarry Smith #define __FUNCT__ "MatAssemblyEnd_IS" 783dfbe8321SBarry Smith PetscErrorCode MatAssemblyEnd_IS(Mat A,MatAssemblyType type) 784b4319ba4SBarry Smith { 785b4319ba4SBarry Smith Mat_IS *is = (Mat_IS*)A->data; 786dfbe8321SBarry Smith PetscErrorCode ierr; 787b4319ba4SBarry Smith 788b4319ba4SBarry Smith PetscFunctionBegin; 789b4319ba4SBarry Smith ierr = MatAssemblyEnd(is->A,type);CHKERRQ(ierr); 790b4319ba4SBarry Smith PetscFunctionReturn(0); 791b4319ba4SBarry Smith } 792b4319ba4SBarry Smith 793b4319ba4SBarry Smith #undef __FUNCT__ 794b4319ba4SBarry Smith #define __FUNCT__ "MatISGetLocalMat_IS" 7957087cfbeSBarry Smith PetscErrorCode MatISGetLocalMat_IS(Mat mat,Mat *local) 796b4319ba4SBarry Smith { 797b4319ba4SBarry Smith Mat_IS *is = (Mat_IS*)mat->data; 798b4319ba4SBarry Smith 799b4319ba4SBarry Smith PetscFunctionBegin; 800b4319ba4SBarry Smith *local = is->A; 801b4319ba4SBarry Smith PetscFunctionReturn(0); 802b4319ba4SBarry Smith } 803b4319ba4SBarry Smith 804b4319ba4SBarry Smith #undef __FUNCT__ 805b4319ba4SBarry Smith #define __FUNCT__ "MatISGetLocalMat" 806b4319ba4SBarry Smith /*@ 807b4319ba4SBarry Smith MatISGetLocalMat - Gets the local matrix stored inside a MATIS matrix. 808b4319ba4SBarry Smith 809b4319ba4SBarry Smith Input Parameter: 810b4319ba4SBarry Smith . mat - the matrix 811b4319ba4SBarry Smith 812b4319ba4SBarry Smith Output Parameter: 813eb82efa4SStefano Zampini . local - the local matrix 814b4319ba4SBarry Smith 815b4319ba4SBarry Smith Level: advanced 816b4319ba4SBarry Smith 817b4319ba4SBarry Smith Notes: 818b4319ba4SBarry Smith This can be called if you have precomputed the nonzero structure of the 819b4319ba4SBarry Smith matrix and want to provide it to the inner matrix object to improve the performance 820b4319ba4SBarry Smith of the MatSetValues() operation. 821b4319ba4SBarry Smith 82296a6f129SJed Brown This function does not increase the reference count for the local Mat. Do not destroy it and do not attempt to use 82396a6f129SJed Brown your reference after destroying the parent mat. 82496a6f129SJed Brown 825b4319ba4SBarry Smith .seealso: MATIS 826b4319ba4SBarry Smith @*/ 8277087cfbeSBarry Smith PetscErrorCode MatISGetLocalMat(Mat mat,Mat *local) 828b4319ba4SBarry Smith { 8294ac538c5SBarry Smith PetscErrorCode ierr; 830b4319ba4SBarry Smith 831b4319ba4SBarry Smith PetscFunctionBegin; 8320700a824SBarry Smith PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 833b4319ba4SBarry Smith PetscValidPointer(local,2); 8344ac538c5SBarry Smith ierr = PetscUseMethod(mat,"MatISGetLocalMat_C",(Mat,Mat*),(mat,local));CHKERRQ(ierr); 835b4319ba4SBarry Smith PetscFunctionReturn(0); 836b4319ba4SBarry Smith } 837b4319ba4SBarry Smith 8383b03a366Sstefano_zampini #undef __FUNCT__ 8393b03a366Sstefano_zampini #define __FUNCT__ "MatISSetLocalMat_IS" 8403b03a366Sstefano_zampini PetscErrorCode MatISSetLocalMat_IS(Mat mat,Mat local) 8413b03a366Sstefano_zampini { 8423b03a366Sstefano_zampini Mat_IS *is = (Mat_IS*)mat->data; 8433b03a366Sstefano_zampini PetscInt nrows,ncols,orows,ocols; 8443b03a366Sstefano_zampini PetscErrorCode ierr; 8453b03a366Sstefano_zampini 8463b03a366Sstefano_zampini PetscFunctionBegin; 8474e4c7dbeSStefano Zampini if (is->A) { 8483b03a366Sstefano_zampini ierr = MatGetSize(is->A,&orows,&ocols);CHKERRQ(ierr); 8493b03a366Sstefano_zampini ierr = MatGetSize(local,&nrows,&ncols);CHKERRQ(ierr); 850f23aa3ddSBarry 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); 8514e4c7dbeSStefano Zampini } 8523b03a366Sstefano_zampini ierr = PetscObjectReference((PetscObject)local);CHKERRQ(ierr); 8533b03a366Sstefano_zampini ierr = MatDestroy(&is->A);CHKERRQ(ierr); 8543b03a366Sstefano_zampini is->A = local; 8553b03a366Sstefano_zampini PetscFunctionReturn(0); 8563b03a366Sstefano_zampini } 8573b03a366Sstefano_zampini 8583b03a366Sstefano_zampini #undef __FUNCT__ 8593b03a366Sstefano_zampini #define __FUNCT__ "MatISSetLocalMat" 8603b03a366Sstefano_zampini /*@ 861eb82efa4SStefano Zampini MatISSetLocalMat - Replace the local matrix stored inside a MATIS object. 8623b03a366Sstefano_zampini 8633b03a366Sstefano_zampini Input Parameter: 8643b03a366Sstefano_zampini . mat - the matrix 865eb82efa4SStefano Zampini . local - the local matrix 8663b03a366Sstefano_zampini 8673b03a366Sstefano_zampini Output Parameter: 8683b03a366Sstefano_zampini 8693b03a366Sstefano_zampini Level: advanced 8703b03a366Sstefano_zampini 8713b03a366Sstefano_zampini Notes: 8723b03a366Sstefano_zampini This can be called if you have precomputed the local matrix and 8733b03a366Sstefano_zampini want to provide it to the matrix object MATIS. 8743b03a366Sstefano_zampini 8753b03a366Sstefano_zampini .seealso: MATIS 8763b03a366Sstefano_zampini @*/ 8773b03a366Sstefano_zampini PetscErrorCode MatISSetLocalMat(Mat mat,Mat local) 8783b03a366Sstefano_zampini { 8793b03a366Sstefano_zampini PetscErrorCode ierr; 8803b03a366Sstefano_zampini 8813b03a366Sstefano_zampini PetscFunctionBegin; 8823b03a366Sstefano_zampini PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 883b7ce53b6SStefano Zampini PetscValidHeaderSpecific(local,MAT_CLASSID,2); 8843b03a366Sstefano_zampini ierr = PetscUseMethod(mat,"MatISSetLocalMat_C",(Mat,Mat),(mat,local));CHKERRQ(ierr); 8853b03a366Sstefano_zampini PetscFunctionReturn(0); 8863b03a366Sstefano_zampini } 8873b03a366Sstefano_zampini 8886726f965SBarry Smith #undef __FUNCT__ 8896726f965SBarry Smith #define __FUNCT__ "MatZeroEntries_IS" 8906726f965SBarry Smith PetscErrorCode MatZeroEntries_IS(Mat A) 8916726f965SBarry Smith { 8926726f965SBarry Smith Mat_IS *a = (Mat_IS*)A->data; 8936726f965SBarry Smith PetscErrorCode ierr; 8946726f965SBarry Smith 8956726f965SBarry Smith PetscFunctionBegin; 8966726f965SBarry Smith ierr = MatZeroEntries(a->A);CHKERRQ(ierr); 8976726f965SBarry Smith PetscFunctionReturn(0); 8986726f965SBarry Smith } 8996726f965SBarry Smith 9006726f965SBarry Smith #undef __FUNCT__ 9012e74eeadSLisandro Dalcin #define __FUNCT__ "MatScale_IS" 9022e74eeadSLisandro Dalcin PetscErrorCode MatScale_IS(Mat A,PetscScalar a) 9032e74eeadSLisandro Dalcin { 9042e74eeadSLisandro Dalcin Mat_IS *is = (Mat_IS*)A->data; 9052e74eeadSLisandro Dalcin PetscErrorCode ierr; 9062e74eeadSLisandro Dalcin 9072e74eeadSLisandro Dalcin PetscFunctionBegin; 9082e74eeadSLisandro Dalcin ierr = MatScale(is->A,a);CHKERRQ(ierr); 9092e74eeadSLisandro Dalcin PetscFunctionReturn(0); 9102e74eeadSLisandro Dalcin } 9112e74eeadSLisandro Dalcin 9122e74eeadSLisandro Dalcin #undef __FUNCT__ 9132e74eeadSLisandro Dalcin #define __FUNCT__ "MatGetDiagonal_IS" 9142e74eeadSLisandro Dalcin PetscErrorCode MatGetDiagonal_IS(Mat A, Vec v) 9152e74eeadSLisandro Dalcin { 9162e74eeadSLisandro Dalcin Mat_IS *is = (Mat_IS*)A->data; 9172e74eeadSLisandro Dalcin PetscErrorCode ierr; 9182e74eeadSLisandro Dalcin 9192e74eeadSLisandro Dalcin PetscFunctionBegin; 9202e74eeadSLisandro Dalcin /* get diagonal of the local matrix */ 921e176bc59SStefano Zampini ierr = MatGetDiagonal(is->A,is->y);CHKERRQ(ierr); 9222e74eeadSLisandro Dalcin 9232e74eeadSLisandro Dalcin /* scatter diagonal back into global vector */ 9242e74eeadSLisandro Dalcin ierr = VecSet(v,0);CHKERRQ(ierr); 925e176bc59SStefano Zampini ierr = VecScatterBegin(is->rctx,is->y,v,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 926e176bc59SStefano Zampini ierr = VecScatterEnd(is->rctx,is->y,v,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 9272e74eeadSLisandro Dalcin PetscFunctionReturn(0); 9282e74eeadSLisandro Dalcin } 9292e74eeadSLisandro Dalcin 9302e74eeadSLisandro Dalcin #undef __FUNCT__ 9316726f965SBarry Smith #define __FUNCT__ "MatSetOption_IS" 932ace3abfcSBarry Smith PetscErrorCode MatSetOption_IS(Mat A,MatOption op,PetscBool flg) 9336726f965SBarry Smith { 9346726f965SBarry Smith Mat_IS *a = (Mat_IS*)A->data; 9356726f965SBarry Smith PetscErrorCode ierr; 9366726f965SBarry Smith 9376726f965SBarry Smith PetscFunctionBegin; 9384e0d8c25SBarry Smith ierr = MatSetOption(a->A,op,flg);CHKERRQ(ierr); 9396726f965SBarry Smith PetscFunctionReturn(0); 9406726f965SBarry Smith } 9416726f965SBarry Smith 942284134d9SBarry Smith #undef __FUNCT__ 943284134d9SBarry Smith #define __FUNCT__ "MatCreateIS" 944284134d9SBarry Smith /*@ 945284134d9SBarry Smith MatCreateIS - Creates a "process" unassmembled matrix, it is assembled on each 946284134d9SBarry Smith process but not across processes. 947284134d9SBarry Smith 948284134d9SBarry Smith Input Parameters: 949284134d9SBarry Smith + comm - MPI communicator that will share the matrix 950e176bc59SStefano Zampini . bs - block size of the matrix 951df3898eeSBarry Smith . m,n,M,N - local and/or global sizes of the left and right vector used in matrix vector products 952e176bc59SStefano Zampini . rmap - local to global map for rows 953e176bc59SStefano Zampini - cmap - local to global map for cols 954284134d9SBarry Smith 955284134d9SBarry Smith Output Parameter: 956284134d9SBarry Smith . A - the resulting matrix 957284134d9SBarry Smith 9588e6c10adSSatish Balay Level: advanced 9598e6c10adSSatish Balay 960284134d9SBarry Smith Notes: See MATIS for more details 9618cda6cd7SBarry Smith m and n are NOT related to the size of the map, they are the size of the part of the vector owned 962e176bc59SStefano Zampini by that process. The sizes of rmap and cmap define the size of the local matrices. 963e176bc59SStefano Zampini If either rmap or cmap are NULL, than the matrix is assumed to be square 964284134d9SBarry Smith 965284134d9SBarry Smith .seealso: MATIS, MatSetLocalToGlobalMapping() 966284134d9SBarry Smith @*/ 967e176bc59SStefano Zampini PetscErrorCode MatCreateIS(MPI_Comm comm,PetscInt bs,PetscInt m,PetscInt n,PetscInt M,PetscInt N,ISLocalToGlobalMapping rmap,ISLocalToGlobalMapping cmap,Mat *A) 968284134d9SBarry Smith { 969284134d9SBarry Smith PetscErrorCode ierr; 970284134d9SBarry Smith 971284134d9SBarry Smith PetscFunctionBegin; 972e176bc59SStefano Zampini if (!rmap && !cmap) SETERRQ(comm,PETSC_ERR_USER,"You need to provide at least one of the mapping"); 973284134d9SBarry Smith ierr = MatCreate(comm,A);CHKERRQ(ierr); 974284134d9SBarry Smith ierr = MatSetSizes(*A,m,n,M,N);CHKERRQ(ierr); 9754f619741Sstefano_zampini ierr = MatSetBlockSize(*A,bs);CHKERRQ(ierr); 976284134d9SBarry Smith ierr = MatSetType(*A,MATIS);CHKERRQ(ierr); 9773b03a366Sstefano_zampini ierr = MatSetUp(*A);CHKERRQ(ierr); 978e176bc59SStefano Zampini if (rmap && cmap) { 979e176bc59SStefano Zampini ierr = MatSetLocalToGlobalMapping(*A,rmap,cmap);CHKERRQ(ierr); 980e176bc59SStefano Zampini } else if (!rmap) { 981e176bc59SStefano Zampini ierr = MatSetLocalToGlobalMapping(*A,cmap,cmap);CHKERRQ(ierr); 982e176bc59SStefano Zampini } else { 983e176bc59SStefano Zampini ierr = MatSetLocalToGlobalMapping(*A,rmap,rmap);CHKERRQ(ierr); 984e176bc59SStefano Zampini } 985284134d9SBarry Smith PetscFunctionReturn(0); 986284134d9SBarry Smith } 987284134d9SBarry Smith 988b4319ba4SBarry Smith /*MC 989eb82efa4SStefano Zampini MATIS - MATIS = "is" - A matrix type to be used for using the non-overlapping domain decomposition type preconditioners (e.g. PCBDDC). 990b4319ba4SBarry Smith This stores the matrices in globally unassembled form. Each processor 991b4319ba4SBarry Smith assembles only its local Neumann problem and the parallel matrix vector 992b4319ba4SBarry Smith product is handled "implicitly". 993b4319ba4SBarry Smith 994b4319ba4SBarry Smith Operations Provided: 9956726f965SBarry Smith + MatMult() 9962e74eeadSLisandro Dalcin . MatMultAdd() 9972e74eeadSLisandro Dalcin . MatMultTranspose() 9982e74eeadSLisandro Dalcin . MatMultTransposeAdd() 9996726f965SBarry Smith . MatZeroEntries() 10006726f965SBarry Smith . MatSetOption() 10012e74eeadSLisandro Dalcin . MatZeroRows() 10026726f965SBarry Smith . MatZeroRowsLocal() 10032e74eeadSLisandro Dalcin . MatSetValues() 10046726f965SBarry Smith . MatSetValuesLocal() 10052e74eeadSLisandro Dalcin . MatScale() 10062e74eeadSLisandro Dalcin . MatGetDiagonal() 10076726f965SBarry Smith - MatSetLocalToGlobalMapping() 1008b4319ba4SBarry Smith 1009b4319ba4SBarry Smith Options Database Keys: 1010b4319ba4SBarry Smith . -mat_type is - sets the matrix type to "is" during a call to MatSetFromOptions() 1011b4319ba4SBarry Smith 1012b4319ba4SBarry Smith Notes: Options prefix for the inner matrix are given by -is_mat_xxx 1013b4319ba4SBarry Smith 1014b4319ba4SBarry Smith You must call MatSetLocalToGlobalMapping() before using this matrix type. 1015b4319ba4SBarry Smith 1016b4319ba4SBarry Smith You can do matrix preallocation on the local matrix after you obtain it with 1017eb82efa4SStefano Zampini MatISGetLocalMat(); otherwise, you could use MatISSetPreallocation() 1018b4319ba4SBarry Smith 1019b4319ba4SBarry Smith Level: advanced 1020b4319ba4SBarry Smith 1021eb82efa4SStefano Zampini .seealso: Mat, MatISGetLocalMat(), MatSetLocalToGlobalMapping(), MatISSetPreallocation(), PCBDDC 1022b4319ba4SBarry Smith 1023b4319ba4SBarry Smith M*/ 1024b4319ba4SBarry Smith 1025b4319ba4SBarry Smith #undef __FUNCT__ 1026b4319ba4SBarry Smith #define __FUNCT__ "MatCreate_IS" 10278cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatCreate_IS(Mat A) 1028b4319ba4SBarry Smith { 1029dfbe8321SBarry Smith PetscErrorCode ierr; 1030b4319ba4SBarry Smith Mat_IS *b; 1031b4319ba4SBarry Smith 1032b4319ba4SBarry Smith PetscFunctionBegin; 1033b00a9115SJed Brown ierr = PetscNewLog(A,&b);CHKERRQ(ierr); 1034b4319ba4SBarry Smith A->data = (void*)b; 1035b4319ba4SBarry Smith 1036e176bc59SStefano Zampini /* matrix ops */ 1037e176bc59SStefano Zampini ierr = PetscMemzero(A->ops,sizeof(struct _MatOps));CHKERRQ(ierr); 1038b4319ba4SBarry Smith A->ops->mult = MatMult_IS; 10392e74eeadSLisandro Dalcin A->ops->multadd = MatMultAdd_IS; 10402e74eeadSLisandro Dalcin A->ops->multtranspose = MatMultTranspose_IS; 10412e74eeadSLisandro Dalcin A->ops->multtransposeadd = MatMultTransposeAdd_IS; 1042b4319ba4SBarry Smith A->ops->destroy = MatDestroy_IS; 1043b4319ba4SBarry Smith A->ops->setlocaltoglobalmapping = MatSetLocalToGlobalMapping_IS; 10442e74eeadSLisandro Dalcin A->ops->setvalues = MatSetValues_IS; 1045b4319ba4SBarry Smith A->ops->setvalueslocal = MatSetValuesLocal_IS; 1046f0006bf2SLisandro Dalcin A->ops->setvaluesblockedlocal = MatSetValuesBlockedLocal_IS; 10472e74eeadSLisandro Dalcin A->ops->zerorows = MatZeroRows_IS; 1048b4319ba4SBarry Smith A->ops->zerorowslocal = MatZeroRowsLocal_IS; 1049b4319ba4SBarry Smith A->ops->assemblybegin = MatAssemblyBegin_IS; 1050b4319ba4SBarry Smith A->ops->assemblyend = MatAssemblyEnd_IS; 1051b4319ba4SBarry Smith A->ops->view = MatView_IS; 10526726f965SBarry Smith A->ops->zeroentries = MatZeroEntries_IS; 10532e74eeadSLisandro Dalcin A->ops->scale = MatScale_IS; 10542e74eeadSLisandro Dalcin A->ops->getdiagonal = MatGetDiagonal_IS; 10556726f965SBarry Smith A->ops->setoption = MatSetOption_IS; 105669796d55SStefano Zampini A->ops->ishermitian = MatIsHermitian_IS; 105769796d55SStefano Zampini A->ops->issymmetric = MatIsSymmetric_IS; 1058ad6194a2SStefano Zampini A->ops->duplicate = MatDuplicate_IS; 1059b4319ba4SBarry Smith 1060b7ce53b6SStefano Zampini /* special MATIS functions */ 1061bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatISGetLocalMat_C",MatISGetLocalMat_IS);CHKERRQ(ierr); 1062bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatISSetLocalMat_C",MatISSetLocalMat_IS);CHKERRQ(ierr); 1063b7ce53b6SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatISGetMPIXAIJ_C",MatISGetMPIXAIJ_IS);CHKERRQ(ierr); 10642e1947a5SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatISSetPreallocation_C",MatISSetPreallocation_IS);CHKERRQ(ierr); 106517667f90SBarry Smith ierr = PetscObjectChangeTypeName((PetscObject)A,MATIS);CHKERRQ(ierr); 1066b4319ba4SBarry Smith PetscFunctionReturn(0); 1067b4319ba4SBarry Smith } 1068