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); 3128f4e0baSStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(matis->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); 3428f4e0baSStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(matis->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" 41a88811baSStefano 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; 962e1947a5SStefano Zampini if (!matis->A) { 972e1947a5SStefano Zampini SETERRQ(PetscObjectComm((PetscObject)B),PETSC_ERR_SUP,"You should first call MatSetLocalToGlobalMapping"); 982e1947a5SStefano Zampini } 9928f4e0baSStefano Zampini if (!matis->sf) { /* setup SF if not yet created and allocate rootdata and leafdata */ 10028f4e0baSStefano Zampini ierr = MatISComputeSF_Private(B);CHKERRQ(ierr); 10128f4e0baSStefano Zampini } 1022e1947a5SStefano Zampini if (!d_nnz) { 10328f4e0baSStefano Zampini for (i=0;i<matis->sf_nroots;i++) matis->sf_rootdata[i] = d_nz; 1042e1947a5SStefano Zampini } else { 10528f4e0baSStefano Zampini for (i=0;i<matis->sf_nroots;i++) matis->sf_rootdata[i] = d_nnz[i]; 1062e1947a5SStefano Zampini } 1072e1947a5SStefano Zampini if (!o_nnz) { 10828f4e0baSStefano Zampini for (i=0;i<matis->sf_nroots;i++) matis->sf_rootdata[i] += o_nz; 1092e1947a5SStefano Zampini } else { 11028f4e0baSStefano Zampini for (i=0;i<matis->sf_nroots;i++) matis->sf_rootdata[i] += o_nnz[i]; 1112e1947a5SStefano Zampini } 11228f4e0baSStefano Zampini ierr = PetscSFBcastBegin(matis->sf,MPIU_INT,matis->sf_rootdata,matis->sf_leafdata);CHKERRQ(ierr); 11328f4e0baSStefano Zampini ierr = MatGetSize(matis->A,NULL,&nlocalcols);CHKERRQ(ierr); 11428f4e0baSStefano Zampini ierr = MatGetBlockSize(matis->A,&bs);CHKERRQ(ierr); 11528f4e0baSStefano Zampini ierr = PetscSFBcastEnd(matis->sf,MPIU_INT,matis->sf_rootdata,matis->sf_leafdata);CHKERRQ(ierr); 11628f4e0baSStefano Zampini for (i=0;i<matis->sf_nleaves;i++) { 11728f4e0baSStefano Zampini matis->sf_leafdata[i] = PetscMin(matis->sf_leafdata[i],nlocalcols); 1182e1947a5SStefano Zampini } 11928f4e0baSStefano Zampini ierr = MatSeqAIJSetPreallocation(matis->A,0,matis->sf_leafdata);CHKERRQ(ierr); 12028f4e0baSStefano Zampini for (i=0;i<matis->sf_nleaves/bs;i++) { 12128f4e0baSStefano Zampini matis->sf_leafdata[i] = matis->sf_leafdata[i*bs]/bs; 1222e1947a5SStefano Zampini } 12328f4e0baSStefano Zampini ierr = MatSeqBAIJSetPreallocation(matis->A,bs,0,matis->sf_leafdata);CHKERRQ(ierr); 12428f4e0baSStefano Zampini for (i=0;i<matis->sf_nleaves/bs;i++) { 12528f4e0baSStefano Zampini matis->sf_leafdata[i] = matis->sf_leafdata[i]-i; 1262e1947a5SStefano Zampini } 12728f4e0baSStefano Zampini ierr = MatSeqSBAIJSetPreallocation(matis->A,bs,0,matis->sf_leafdata);CHKERRQ(ierr); 1282e1947a5SStefano Zampini PetscFunctionReturn(0); 1292e1947a5SStefano Zampini } 130b4319ba4SBarry Smith 131b4319ba4SBarry Smith #undef __FUNCT__ 1323927de2eSStefano Zampini #define __FUNCT__ "MatISSetMPIXAIJPreallocation_Private" 1333927de2eSStefano Zampini PETSC_EXTERN PetscErrorCode MatISSetMPIXAIJPreallocation_Private(Mat A, Mat B, PetscBool maxreduce) 1343927de2eSStefano Zampini { 1353927de2eSStefano Zampini Mat_IS *matis = (Mat_IS*)(A->data); 1363927de2eSStefano Zampini PetscInt *my_dnz,*my_onz,*dnz,*onz,*mat_ranges,*row_ownership; 1373927de2eSStefano Zampini const PetscInt* global_indices; 1383927de2eSStefano Zampini PetscInt i,j,bs,rows,cols; 1393927de2eSStefano Zampini PetscInt lrows,lcols; 1403927de2eSStefano Zampini PetscInt local_rows,local_cols; 1413927de2eSStefano Zampini PetscMPIInt nsubdomains; 1423927de2eSStefano Zampini PetscBool isdense,issbaij; 1433927de2eSStefano Zampini PetscErrorCode ierr; 1443927de2eSStefano Zampini 1453927de2eSStefano Zampini PetscFunctionBegin; 1463927de2eSStefano Zampini ierr = MPI_Comm_size(PetscObjectComm((PetscObject)A),&nsubdomains);CHKERRQ(ierr); 1473927de2eSStefano Zampini ierr = MatGetSize(A,&rows,&cols);CHKERRQ(ierr); 1483927de2eSStefano Zampini ierr = MatGetBlockSize(A,&bs);CHKERRQ(ierr); 1493927de2eSStefano Zampini ierr = MatGetSize(matis->A,&local_rows,&local_cols);CHKERRQ(ierr); 1503927de2eSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)matis->A,MATSEQDENSE,&isdense);CHKERRQ(ierr); 1513927de2eSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)matis->A,MATSEQSBAIJ,&issbaij);CHKERRQ(ierr); 1523927de2eSStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(matis->mapping,&global_indices);CHKERRQ(ierr); 1533927de2eSStefano Zampini if (issbaij) { 1543927de2eSStefano Zampini ierr = MatGetRowUpperTriangular(matis->A);CHKERRQ(ierr); 1553927de2eSStefano Zampini } 1563927de2eSStefano Zampini /* 1573927de2eSStefano Zampini An SF reduce is needed to sum up properly on shared interface dofs. 1583927de2eSStefano Zampini Note that generally preallocation is not exact, since it overestimates nonzeros 1593927de2eSStefano Zampini */ 1603927de2eSStefano Zampini if (!matis->sf) { /* setup SF if not yet created and allocate rootdata and leafdata */ 1613927de2eSStefano Zampini ierr = MatISComputeSF_Private(A);CHKERRQ(ierr); 1623927de2eSStefano Zampini } 1633927de2eSStefano Zampini ierr = MatGetLocalSize(A,&lrows,&lcols);CHKERRQ(ierr); 1643927de2eSStefano Zampini ierr = MatPreallocateInitialize(PetscObjectComm((PetscObject)A),lrows,lcols,dnz,onz);CHKERRQ(ierr); 1653927de2eSStefano Zampini /* All processes need to compute entire row ownership */ 1663927de2eSStefano Zampini ierr = PetscMalloc1(rows,&row_ownership);CHKERRQ(ierr); 1673927de2eSStefano Zampini ierr = MatGetOwnershipRanges(A,(const PetscInt**)&mat_ranges);CHKERRQ(ierr); 1683927de2eSStefano Zampini for (i=0;i<nsubdomains;i++) { 1693927de2eSStefano Zampini for (j=mat_ranges[i];j<mat_ranges[i+1];j++) { 1703927de2eSStefano Zampini row_ownership[j]=i; 1713927de2eSStefano Zampini } 1723927de2eSStefano Zampini } 1733927de2eSStefano Zampini 1743927de2eSStefano Zampini /* 1753927de2eSStefano Zampini my_dnz and my_onz contains exact contribution to preallocation from each local mat 1763927de2eSStefano Zampini then, they will be summed up properly. This way, preallocation is always sufficient 1773927de2eSStefano Zampini */ 1783927de2eSStefano Zampini ierr = PetscCalloc2(local_rows,&my_dnz,local_rows,&my_onz);CHKERRQ(ierr); 1793927de2eSStefano Zampini /* preallocation as a MATAIJ */ 1803927de2eSStefano Zampini if (isdense) { /* special case for dense local matrices */ 1813927de2eSStefano Zampini for (i=0;i<local_rows;i++) { 1823927de2eSStefano Zampini PetscInt index_row = global_indices[i]; 1833927de2eSStefano Zampini for (j=i;j<local_rows;j++) { 1843927de2eSStefano Zampini PetscInt owner = row_ownership[index_row]; 1853927de2eSStefano Zampini PetscInt index_col = global_indices[j]; 1863927de2eSStefano Zampini if (index_col > mat_ranges[owner]-1 && index_col < mat_ranges[owner+1] ) { /* diag block */ 1873927de2eSStefano Zampini my_dnz[i] += 1; 1883927de2eSStefano Zampini } else { /* offdiag block */ 1893927de2eSStefano Zampini my_onz[i] += 1; 1903927de2eSStefano Zampini } 1913927de2eSStefano Zampini /* same as before, interchanging rows and cols */ 1923927de2eSStefano Zampini if (i != j) { 1933927de2eSStefano Zampini owner = row_ownership[index_col]; 1943927de2eSStefano Zampini if (index_row > mat_ranges[owner]-1 && index_row < mat_ranges[owner+1] ) { 1953927de2eSStefano Zampini my_dnz[j] += 1; 1963927de2eSStefano Zampini } else { 1973927de2eSStefano Zampini my_onz[j] += 1; 1983927de2eSStefano Zampini } 1993927de2eSStefano Zampini } 2003927de2eSStefano Zampini } 2013927de2eSStefano Zampini } 2023927de2eSStefano Zampini } else { 2033927de2eSStefano Zampini for (i=0;i<local_rows;i++) { 2043927de2eSStefano Zampini const PetscInt *cols; 2053927de2eSStefano Zampini PetscInt ncols,index_row = global_indices[i]; 2063927de2eSStefano Zampini ierr = MatGetRow(matis->A,i,&ncols,&cols,NULL);CHKERRQ(ierr); 2073927de2eSStefano Zampini for (j=0;j<ncols;j++) { 2083927de2eSStefano Zampini PetscInt owner = row_ownership[index_row]; 2093927de2eSStefano Zampini PetscInt index_col = global_indices[cols[j]]; 2103927de2eSStefano Zampini if (index_col > mat_ranges[owner]-1 && index_col < mat_ranges[owner+1] ) { /* diag block */ 2113927de2eSStefano Zampini my_dnz[i] += 1; 2123927de2eSStefano Zampini } else { /* offdiag block */ 2133927de2eSStefano Zampini my_onz[i] += 1; 2143927de2eSStefano Zampini } 2153927de2eSStefano Zampini /* same as before, interchanging rows and cols */ 2163927de2eSStefano Zampini if (issbaij) { 2173927de2eSStefano Zampini owner = row_ownership[index_col]; 2183927de2eSStefano Zampini if (index_row > mat_ranges[owner]-1 && index_row < mat_ranges[owner+1] ) { 2193927de2eSStefano Zampini my_dnz[j] += 1; 2203927de2eSStefano Zampini } else { 2213927de2eSStefano Zampini my_onz[j] += 1; 2223927de2eSStefano Zampini } 2233927de2eSStefano Zampini } 2243927de2eSStefano Zampini } 2253927de2eSStefano Zampini ierr = MatRestoreRow(matis->A,i,&ncols,&cols,NULL);CHKERRQ(ierr); 2263927de2eSStefano Zampini } 2273927de2eSStefano Zampini } 2283927de2eSStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(matis->mapping,&global_indices);CHKERRQ(ierr); 2293927de2eSStefano Zampini ierr = PetscFree(row_ownership);CHKERRQ(ierr); 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 for (i=0;i<lrows/bs;i++) { 2563927de2eSStefano Zampini dnz[i] = dnz[i]-i; 2573927de2eSStefano Zampini } 2583927de2eSStefano Zampini ierr = MatMPISBAIJSetPreallocation(B,bs,0,dnz,0,onz);CHKERRQ(ierr); 2593927de2eSStefano Zampini ierr = MatPreallocateFinalize(dnz,onz);CHKERRQ(ierr); 2603927de2eSStefano Zampini if (issbaij) { 2613927de2eSStefano Zampini ierr = MatRestoreRowUpperTriangular(matis->A);CHKERRQ(ierr); 2623927de2eSStefano Zampini } 2633927de2eSStefano Zampini PetscFunctionReturn(0); 2643927de2eSStefano Zampini } 2653927de2eSStefano Zampini 2663927de2eSStefano Zampini #undef __FUNCT__ 267b7ce53b6SStefano Zampini #define __FUNCT__ "MatISGetMPIXAIJ_IS" 268b7ce53b6SStefano Zampini PetscErrorCode MatISGetMPIXAIJ_IS(Mat mat, MatReuse reuse, Mat *M) 269b7ce53b6SStefano Zampini { 270b7ce53b6SStefano Zampini Mat_IS *matis = (Mat_IS*)(mat->data); 271b7ce53b6SStefano Zampini /* info on mat */ 272b7ce53b6SStefano Zampini /* ISLocalToGlobalMapping rmapping,cmapping; */ 273b7ce53b6SStefano Zampini PetscInt bs,rows,cols; 274b7ce53b6SStefano Zampini PetscInt local_rows,local_cols; 275686e3a49SStefano Zampini PetscBool isdense,issbaij,isseqaij; 276686e3a49SStefano Zampini const PetscInt *global_indices_rows; 2777c03b4e8SStefano Zampini PetscMPIInt nsubdomains; 278b7ce53b6SStefano Zampini /* values insertion */ 279b7ce53b6SStefano Zampini PetscScalar *array; 280b7ce53b6SStefano Zampini /* work */ 281b7ce53b6SStefano Zampini PetscErrorCode ierr; 282b7ce53b6SStefano Zampini 283b7ce53b6SStefano Zampini PetscFunctionBegin; 284b7ce53b6SStefano Zampini /* MISSING CHECKS 285b7ce53b6SStefano Zampini - rectangular case not covered (it is not allowed by MATIS) 286b7ce53b6SStefano Zampini */ 287b7ce53b6SStefano Zampini /* get info from mat */ 2887c03b4e8SStefano Zampini ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&nsubdomains);CHKERRQ(ierr); 2897c03b4e8SStefano Zampini if (nsubdomains == 1) { 2907c03b4e8SStefano Zampini if (reuse == MAT_INITIAL_MATRIX) { 2917c03b4e8SStefano Zampini ierr = MatDuplicate(matis->A,MAT_COPY_VALUES,&(*M));CHKERRQ(ierr); 2927c03b4e8SStefano Zampini } else { 2937c03b4e8SStefano Zampini ierr = MatCopy(matis->A,*M,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 2947c03b4e8SStefano Zampini } 2957c03b4e8SStefano Zampini PetscFunctionReturn(0); 2967c03b4e8SStefano Zampini } 297b7ce53b6SStefano Zampini /* ierr = MatGetLocalToGlobalMapping(mat,&rmapping,&cmapping);CHKERRQ(ierr); */ 298b7ce53b6SStefano Zampini ierr = MatGetSize(mat,&rows,&cols);CHKERRQ(ierr); 299b7ce53b6SStefano Zampini ierr = MatGetBlockSize(mat,&bs);CHKERRQ(ierr); 300b7ce53b6SStefano Zampini ierr = MatGetSize(matis->A,&local_rows,&local_cols);CHKERRQ(ierr); 301b7ce53b6SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)matis->A,MATSEQDENSE,&isdense);CHKERRQ(ierr); 302686e3a49SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)matis->A,MATSEQAIJ,&isseqaij);CHKERRQ(ierr); 303b7ce53b6SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)matis->A,MATSEQSBAIJ,&issbaij);CHKERRQ(ierr); 304b7ce53b6SStefano Zampini 305686e3a49SStefano Zampini /* map indices of local mat rows to global values */ 306686e3a49SStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(matis->mapping,&global_indices_rows);CHKERRQ(ierr); 307b7ce53b6SStefano Zampini 308b7ce53b6SStefano Zampini if (issbaij) { 309b7ce53b6SStefano Zampini ierr = MatGetRowUpperTriangular(matis->A);CHKERRQ(ierr); 310b7ce53b6SStefano Zampini } 311b7ce53b6SStefano Zampini 312b7ce53b6SStefano Zampini if (reuse == MAT_INITIAL_MATRIX) { 313b7ce53b6SStefano Zampini MatType new_mat_type; 3143927de2eSStefano Zampini PetscBool issbaij_red; 315b7ce53b6SStefano Zampini 316b7ce53b6SStefano Zampini /* determining new matrix type */ 317b7ce53b6SStefano Zampini ierr = MPI_Allreduce(&issbaij,&issbaij_red,1,MPIU_BOOL,MPI_LAND,PetscObjectComm((PetscObject)mat));CHKERRQ(ierr); 318b7ce53b6SStefano Zampini if (issbaij_red) { 319b7ce53b6SStefano Zampini new_mat_type = MATSBAIJ; 320b7ce53b6SStefano Zampini } else { 321b7ce53b6SStefano Zampini if (bs>1) { 322b7ce53b6SStefano Zampini new_mat_type = MATBAIJ; 323b7ce53b6SStefano Zampini } else { 324b7ce53b6SStefano Zampini new_mat_type = MATAIJ; 325b7ce53b6SStefano Zampini } 326b7ce53b6SStefano Zampini } 327b7ce53b6SStefano Zampini 3283927de2eSStefano Zampini ierr = MatCreate(PetscObjectComm((PetscObject)mat),M);CHKERRQ(ierr); 3293927de2eSStefano Zampini ierr = MatSetSizes(*M,PETSC_DECIDE,PETSC_DECIDE,rows,cols);CHKERRQ(ierr); 3303927de2eSStefano Zampini ierr = MatSetBlockSize(*M,bs);CHKERRQ(ierr); 3313927de2eSStefano Zampini ierr = MatSetType(*M,new_mat_type);CHKERRQ(ierr); 3323927de2eSStefano Zampini ierr = MatISSetMPIXAIJPreallocation_Private(mat,*M,PETSC_FALSE);CHKERRQ(ierr); 333b7ce53b6SStefano Zampini } else { 334b7ce53b6SStefano Zampini PetscInt mbs,mrows,mcols; 335b7ce53b6SStefano Zampini /* some checks */ 336b7ce53b6SStefano Zampini ierr = MatGetBlockSize(*M,&mbs);CHKERRQ(ierr); 337b7ce53b6SStefano Zampini ierr = MatGetSize(*M,&mrows,&mcols);CHKERRQ(ierr); 338b7ce53b6SStefano Zampini if (mrows != rows) { 339b7ce53b6SStefano Zampini SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot reuse matrix. Wrong number of rows (%d != %d)",rows,mrows); 340b7ce53b6SStefano Zampini } 341b7ce53b6SStefano Zampini if (mrows != rows) { 342b7ce53b6SStefano Zampini SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot reuse matrix. Wrong number of cols (%d != %d)",cols,mcols); 343b7ce53b6SStefano Zampini } 344b7ce53b6SStefano Zampini if (mbs != bs) { 345b7ce53b6SStefano Zampini SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot reuse matrix. Wrong block size (%d != %d)",bs,mbs); 346b7ce53b6SStefano Zampini } 347b7ce53b6SStefano Zampini ierr = MatZeroEntries(*M);CHKERRQ(ierr); 348b7ce53b6SStefano Zampini } 349b7ce53b6SStefano Zampini /* set local to global mappings */ 350*c0962df8SStefano Zampini /* ierr = MatSetLocalToGlobalMapping(*M,matis->mapping,matis->mapping);CHKERRQ(ierr); */ 351686e3a49SStefano Zampini 352b7ce53b6SStefano Zampini /* Set values */ 353b7ce53b6SStefano Zampini if (isdense) { /* special case for dense local matrices */ 354b7ce53b6SStefano Zampini ierr = MatSetOption(*M,MAT_ROW_ORIENTED,PETSC_FALSE);CHKERRQ(ierr); 355b7ce53b6SStefano Zampini ierr = MatDenseGetArray(matis->A,&array);CHKERRQ(ierr); 356686e3a49SStefano Zampini ierr = MatSetValues(*M,local_rows,global_indices_rows,local_cols,global_indices_rows,array,ADD_VALUES);CHKERRQ(ierr); 357b7ce53b6SStefano Zampini ierr = MatDenseRestoreArray(matis->A,&array);CHKERRQ(ierr); 358686e3a49SStefano Zampini } else if (isseqaij) { 359686e3a49SStefano Zampini PetscInt i,nvtxs,*xadj,*adjncy,*global_indices_cols; 360686e3a49SStefano Zampini PetscBool done; 361686e3a49SStefano Zampini 362686e3a49SStefano Zampini ierr = MatGetRowIJ(matis->A,0,PETSC_FALSE,PETSC_FALSE,&nvtxs,(const PetscInt**)&xadj,(const PetscInt**)&adjncy,&done);CHKERRQ(ierr); 363686e3a49SStefano Zampini if (!done) { 364686e3a49SStefano Zampini SETERRQ1(PetscObjectComm((PetscObject)matis->A),PETSC_ERR_PLIB,"Error in MatRestoreRowIJ called in %s\n",__FUNCT__); 365b7ce53b6SStefano Zampini } 366686e3a49SStefano Zampini ierr = MatSeqAIJGetArray(matis->A,&array);CHKERRQ(ierr); 367686e3a49SStefano Zampini ierr = PetscMalloc1(xadj[nvtxs],&global_indices_cols);CHKERRQ(ierr); 368686e3a49SStefano Zampini ierr = ISLocalToGlobalMappingApply(matis->mapping,xadj[nvtxs],adjncy,global_indices_cols);CHKERRQ(ierr); 369686e3a49SStefano Zampini for (i=0;i<nvtxs;i++) { 370686e3a49SStefano Zampini PetscInt row,*cols,ncols; 371686e3a49SStefano Zampini PetscScalar *mat_vals; 372686e3a49SStefano Zampini 373686e3a49SStefano Zampini row = global_indices_rows[i]; 374686e3a49SStefano Zampini ncols = xadj[i+1]-xadj[i]; 375686e3a49SStefano Zampini cols = global_indices_cols+xadj[i]; 376686e3a49SStefano Zampini mat_vals = array+xadj[i]; 377686e3a49SStefano Zampini ierr = MatSetValues(*M,1,&row,ncols,cols,mat_vals,ADD_VALUES);CHKERRQ(ierr); 378686e3a49SStefano Zampini } 379686e3a49SStefano Zampini ierr = MatRestoreRowIJ(matis->A,0,PETSC_FALSE,PETSC_FALSE,&nvtxs,(const PetscInt**)&xadj,(const PetscInt**)&adjncy,&done);CHKERRQ(ierr); 380686e3a49SStefano Zampini if (!done) { 381686e3a49SStefano Zampini SETERRQ1(PetscObjectComm((PetscObject)matis->A),PETSC_ERR_PLIB,"Error in MatRestoreRowIJ called in %s\n",__FUNCT__); 382686e3a49SStefano Zampini } 383686e3a49SStefano Zampini ierr = MatSeqAIJRestoreArray(matis->A,&array);CHKERRQ(ierr); 384686e3a49SStefano Zampini ierr = PetscFree(global_indices_cols);CHKERRQ(ierr); 385686e3a49SStefano Zampini } else { /* very basic values insertion for all other matrix types */ 386*c0962df8SStefano Zampini PetscInt i,*global_indices_cols; 387*c0962df8SStefano Zampini 388*c0962df8SStefano Zampini ierr = PetscMalloc1(local_cols,&global_indices_cols);CHKERRQ(ierr); 389686e3a49SStefano Zampini for (i=0;i<local_rows;i++) { 390686e3a49SStefano Zampini PetscInt j; 391686e3a49SStefano Zampini const PetscInt *local_indices; 392686e3a49SStefano Zampini 393686e3a49SStefano Zampini ierr = MatGetRow(matis->A,i,&j,&local_indices,(const PetscScalar**)&array);CHKERRQ(ierr); 394*c0962df8SStefano Zampini ierr = ISLocalToGlobalMappingApply(matis->mapping,j,local_indices,global_indices_cols);CHKERRQ(ierr); 395*c0962df8SStefano Zampini ierr = MatSetValues(*M,1,&global_indices_rows[i],j,global_indices_cols,array,ADD_VALUES);CHKERRQ(ierr); 396686e3a49SStefano Zampini ierr = MatRestoreRow(matis->A,i,&j,&local_indices,(const PetscScalar**)&array);CHKERRQ(ierr); 397686e3a49SStefano Zampini } 398*c0962df8SStefano Zampini ierr = PetscFree(global_indices_cols);CHKERRQ(ierr); 399b7ce53b6SStefano Zampini } 400b7ce53b6SStefano Zampini ierr = MatAssemblyBegin(*M,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 401b7ce53b6SStefano Zampini ierr = MatAssemblyEnd(*M,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 402b7ce53b6SStefano Zampini if (isdense) { 403b7ce53b6SStefano Zampini ierr = MatSetOption(*M,MAT_ROW_ORIENTED,PETSC_TRUE);CHKERRQ(ierr); 404b7ce53b6SStefano Zampini } 405b7ce53b6SStefano Zampini if (issbaij) { 406b7ce53b6SStefano Zampini ierr = MatRestoreRowUpperTriangular(matis->A);CHKERRQ(ierr); 407b7ce53b6SStefano Zampini } 408686e3a49SStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(matis->mapping,&global_indices_rows);CHKERRQ(ierr); 409b7ce53b6SStefano Zampini PetscFunctionReturn(0); 410b7ce53b6SStefano Zampini } 411b7ce53b6SStefano Zampini 412b7ce53b6SStefano Zampini #undef __FUNCT__ 413b7ce53b6SStefano Zampini #define __FUNCT__ "MatISGetMPIXAIJ" 414b7ce53b6SStefano Zampini /*@ 415b7ce53b6SStefano Zampini MatISGetMPIXAIJ - Converts MATIS matrix into a parallel AIJ format 416b7ce53b6SStefano Zampini 417b7ce53b6SStefano Zampini Input Parameter: 418b7ce53b6SStefano Zampini . mat - the matrix (should be of type MATIS) 419b7ce53b6SStefano Zampini . reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 420b7ce53b6SStefano Zampini 421b7ce53b6SStefano Zampini Output Parameter: 422b7ce53b6SStefano Zampini . newmat - the matrix in AIJ format 423b7ce53b6SStefano Zampini 424b7ce53b6SStefano Zampini Level: developer 425b7ce53b6SStefano Zampini 426b7ce53b6SStefano Zampini Notes: 427b7ce53b6SStefano Zampini 428b7ce53b6SStefano Zampini .seealso: MATIS 429b7ce53b6SStefano Zampini @*/ 430b7ce53b6SStefano Zampini PetscErrorCode MatISGetMPIXAIJ(Mat mat, MatReuse reuse, Mat *newmat) 431b7ce53b6SStefano Zampini { 432b7ce53b6SStefano Zampini PetscErrorCode ierr; 433b7ce53b6SStefano Zampini 434b7ce53b6SStefano Zampini PetscFunctionBegin; 435b7ce53b6SStefano Zampini PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 436b7ce53b6SStefano Zampini PetscValidLogicalCollectiveEnum(mat,reuse,2); 437b7ce53b6SStefano Zampini PetscValidPointer(newmat,3); 438b7ce53b6SStefano Zampini if (reuse != MAT_INITIAL_MATRIX) { 439b7ce53b6SStefano Zampini PetscValidHeaderSpecific(*newmat,MAT_CLASSID,3); 440b7ce53b6SStefano Zampini PetscCheckSameComm(mat,1,*newmat,3); 441b7ce53b6SStefano Zampini } 442b7ce53b6SStefano Zampini ierr = PetscUseMethod(mat,"MatISGetMPIXAIJ_C",(Mat,MatReuse,Mat*),(mat,reuse,newmat));CHKERRQ(ierr); 443b7ce53b6SStefano Zampini PetscFunctionReturn(0); 444b7ce53b6SStefano Zampini } 445b7ce53b6SStefano Zampini 446b7ce53b6SStefano Zampini #undef __FUNCT__ 447ad6194a2SStefano Zampini #define __FUNCT__ "MatDuplicate_IS" 448ad6194a2SStefano Zampini PetscErrorCode MatDuplicate_IS(Mat mat,MatDuplicateOption op,Mat *newmat) 449ad6194a2SStefano Zampini { 450ad6194a2SStefano Zampini PetscErrorCode ierr; 451ad6194a2SStefano Zampini Mat_IS *matis = (Mat_IS*)(mat->data); 452ad6194a2SStefano Zampini PetscInt bs,m,n,M,N; 453ad6194a2SStefano Zampini Mat B,localmat; 454ad6194a2SStefano Zampini 455ad6194a2SStefano Zampini PetscFunctionBegin; 456ad6194a2SStefano Zampini ierr = MatGetBlockSize(mat,&bs);CHKERRQ(ierr); 457ad6194a2SStefano Zampini ierr = MatGetSize(mat,&M,&N);CHKERRQ(ierr); 458ad6194a2SStefano Zampini ierr = MatGetLocalSize(mat,&m,&n);CHKERRQ(ierr); 459ad6194a2SStefano Zampini ierr = MatCreateIS(PetscObjectComm((PetscObject)mat),bs,m,n,M,N,matis->mapping,&B);CHKERRQ(ierr); 460ad6194a2SStefano Zampini ierr = MatDuplicate(matis->A,op,&localmat);CHKERRQ(ierr); 461ad6194a2SStefano Zampini ierr = MatISSetLocalMat(B,localmat);CHKERRQ(ierr); 462b3317aa8SStefano Zampini ierr = MatDestroy(&localmat);CHKERRQ(ierr); 463ad6194a2SStefano Zampini ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 464ad6194a2SStefano Zampini ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 465ad6194a2SStefano Zampini *newmat = B; 466ad6194a2SStefano Zampini PetscFunctionReturn(0); 467ad6194a2SStefano Zampini } 468ad6194a2SStefano Zampini 469ad6194a2SStefano Zampini #undef __FUNCT__ 47069796d55SStefano Zampini #define __FUNCT__ "MatIsHermitian_IS" 47169796d55SStefano Zampini PetscErrorCode MatIsHermitian_IS(Mat A,PetscReal tol,PetscBool *flg) 47269796d55SStefano Zampini { 47369796d55SStefano Zampini PetscErrorCode ierr; 47469796d55SStefano Zampini Mat_IS *matis = (Mat_IS*)A->data; 47569796d55SStefano Zampini PetscBool local_sym; 47669796d55SStefano Zampini 47769796d55SStefano Zampini PetscFunctionBegin; 47869796d55SStefano Zampini ierr = MatIsHermitian(matis->A,tol,&local_sym);CHKERRQ(ierr); 47969796d55SStefano Zampini ierr = MPI_Allreduce(&local_sym,flg,1,MPIU_BOOL,MPI_LAND,PetscObjectComm((PetscObject)A));CHKERRQ(ierr); 48069796d55SStefano Zampini PetscFunctionReturn(0); 48169796d55SStefano Zampini } 48269796d55SStefano Zampini 48369796d55SStefano Zampini #undef __FUNCT__ 48469796d55SStefano Zampini #define __FUNCT__ "MatIsSymmetric_IS" 48569796d55SStefano Zampini PetscErrorCode MatIsSymmetric_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 = MatIsSymmetric(matis->A,tol,&local_sym);CHKERRQ(ierr); 49369796d55SStefano Zampini ierr = MPI_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__ 498b4319ba4SBarry Smith #define __FUNCT__ "MatDestroy_IS" 499dfbe8321SBarry Smith PetscErrorCode MatDestroy_IS(Mat A) 500b4319ba4SBarry Smith { 501dfbe8321SBarry Smith PetscErrorCode ierr; 502b4319ba4SBarry Smith Mat_IS *b = (Mat_IS*)A->data; 503b4319ba4SBarry Smith 504b4319ba4SBarry Smith PetscFunctionBegin; 5056bf464f9SBarry Smith ierr = MatDestroy(&b->A);CHKERRQ(ierr); 5066bf464f9SBarry Smith ierr = VecScatterDestroy(&b->ctx);CHKERRQ(ierr); 5076bf464f9SBarry Smith ierr = VecDestroy(&b->x);CHKERRQ(ierr); 5086bf464f9SBarry Smith ierr = VecDestroy(&b->y);CHKERRQ(ierr); 5096bf464f9SBarry Smith ierr = ISLocalToGlobalMappingDestroy(&b->mapping);CHKERRQ(ierr); 51028f4e0baSStefano Zampini ierr = PetscSFDestroy(&b->sf);CHKERRQ(ierr); 51128f4e0baSStefano Zampini ierr = PetscFree2(b->sf_rootdata,b->sf_leafdata);CHKERRQ(ierr); 512bf0cc555SLisandro Dalcin ierr = PetscFree(A->data);CHKERRQ(ierr); 513dbd8c25aSHong Zhang ierr = PetscObjectChangeTypeName((PetscObject)A,0);CHKERRQ(ierr); 514bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatISGetLocalMat_C",NULL);CHKERRQ(ierr); 515b7ce53b6SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatISSetLocalMat_C",NULL);CHKERRQ(ierr); 516b7ce53b6SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatISGetMPIXAIJ_C",NULL);CHKERRQ(ierr); 5172e1947a5SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatISSetPreallocation_C",NULL);CHKERRQ(ierr); 518b4319ba4SBarry Smith PetscFunctionReturn(0); 519b4319ba4SBarry Smith } 520b4319ba4SBarry Smith 521b4319ba4SBarry Smith #undef __FUNCT__ 522b4319ba4SBarry Smith #define __FUNCT__ "MatMult_IS" 523dfbe8321SBarry Smith PetscErrorCode MatMult_IS(Mat A,Vec x,Vec y) 524b4319ba4SBarry Smith { 525dfbe8321SBarry Smith PetscErrorCode ierr; 526b4319ba4SBarry Smith Mat_IS *is = (Mat_IS*)A->data; 527b4319ba4SBarry Smith PetscScalar zero = 0.0; 528b4319ba4SBarry Smith 529b4319ba4SBarry Smith PetscFunctionBegin; 530b4319ba4SBarry Smith /* scatter the global vector x into the local work vector */ 531ca9f406cSSatish Balay ierr = VecScatterBegin(is->ctx,x,is->x,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 532ca9f406cSSatish Balay ierr = VecScatterEnd(is->ctx,x,is->x,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 533b4319ba4SBarry Smith 534b4319ba4SBarry Smith /* multiply the local matrix */ 535b4319ba4SBarry Smith ierr = MatMult(is->A,is->x,is->y);CHKERRQ(ierr); 536b4319ba4SBarry Smith 537b4319ba4SBarry Smith /* scatter product back into global memory */ 5382dcb1b2aSMatthew Knepley ierr = VecSet(y,zero);CHKERRQ(ierr); 539ca9f406cSSatish Balay ierr = VecScatterBegin(is->ctx,is->y,y,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 540ca9f406cSSatish Balay ierr = VecScatterEnd(is->ctx,is->y,y,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 541b4319ba4SBarry Smith PetscFunctionReturn(0); 542b4319ba4SBarry Smith } 543b4319ba4SBarry Smith 544b4319ba4SBarry Smith #undef __FUNCT__ 5452e74eeadSLisandro Dalcin #define __FUNCT__ "MatMultAdd_IS" 546b7ce53b6SStefano Zampini PetscErrorCode MatMultAdd_IS(Mat A,Vec v1,Vec v2,Vec v3) 5472e74eeadSLisandro Dalcin { 548650997f4SStefano Zampini Vec temp_vec; 5492e74eeadSLisandro Dalcin PetscErrorCode ierr; 5502e74eeadSLisandro Dalcin 5512e74eeadSLisandro Dalcin PetscFunctionBegin; /* v3 = v2 + A * v1.*/ 552650997f4SStefano Zampini if (v3 != v2) { 553650997f4SStefano Zampini ierr = MatMult(A,v1,v3);CHKERRQ(ierr); 554650997f4SStefano Zampini ierr = VecAXPY(v3,1.0,v2);CHKERRQ(ierr); 555650997f4SStefano Zampini } else { 556650997f4SStefano Zampini ierr = VecDuplicate(v2,&temp_vec);CHKERRQ(ierr); 557650997f4SStefano Zampini ierr = MatMult(A,v1,temp_vec);CHKERRQ(ierr); 558650997f4SStefano Zampini ierr = VecAXPY(temp_vec,1.0,v2);CHKERRQ(ierr); 559650997f4SStefano Zampini ierr = VecCopy(temp_vec,v3);CHKERRQ(ierr); 560650997f4SStefano Zampini ierr = VecDestroy(&temp_vec);CHKERRQ(ierr); 561650997f4SStefano Zampini } 5622e74eeadSLisandro Dalcin PetscFunctionReturn(0); 5632e74eeadSLisandro Dalcin } 5642e74eeadSLisandro Dalcin 5652e74eeadSLisandro Dalcin #undef __FUNCT__ 5662e74eeadSLisandro Dalcin #define __FUNCT__ "MatMultTranspose_IS" 5672e74eeadSLisandro Dalcin PetscErrorCode MatMultTranspose_IS(Mat A,Vec x,Vec y) 5682e74eeadSLisandro Dalcin { 5692e74eeadSLisandro Dalcin Mat_IS *is = (Mat_IS*)A->data; 5702e74eeadSLisandro Dalcin PetscErrorCode ierr; 5712e74eeadSLisandro Dalcin 5722e74eeadSLisandro Dalcin PetscFunctionBegin; /* y = A' * x */ 5732e74eeadSLisandro Dalcin /* scatter the global vector x into the local work vector */ 574ca9f406cSSatish Balay ierr = VecScatterBegin(is->ctx,x,is->x,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 575ca9f406cSSatish Balay ierr = VecScatterEnd(is->ctx,x,is->x,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 5762e74eeadSLisandro Dalcin 5772e74eeadSLisandro Dalcin /* multiply the local matrix */ 5782e74eeadSLisandro Dalcin ierr = MatMultTranspose(is->A,is->x,is->y);CHKERRQ(ierr); 5792e74eeadSLisandro Dalcin 5802e74eeadSLisandro Dalcin /* scatter product back into global vector */ 5812e74eeadSLisandro Dalcin ierr = VecSet(y,0);CHKERRQ(ierr); 582ca9f406cSSatish Balay ierr = VecScatterBegin(is->ctx,is->y,y,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 583ca9f406cSSatish Balay ierr = VecScatterEnd(is->ctx,is->y,y,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 5842e74eeadSLisandro Dalcin PetscFunctionReturn(0); 5852e74eeadSLisandro Dalcin } 5862e74eeadSLisandro Dalcin 5872e74eeadSLisandro Dalcin #undef __FUNCT__ 5882e74eeadSLisandro Dalcin #define __FUNCT__ "MatMultTransposeAdd_IS" 5892e74eeadSLisandro Dalcin PetscErrorCode MatMultTransposeAdd_IS(Mat A,Vec v1,Vec v2,Vec v3) 5902e74eeadSLisandro Dalcin { 591650997f4SStefano Zampini Vec temp_vec; 5922e74eeadSLisandro Dalcin PetscErrorCode ierr; 5932e74eeadSLisandro Dalcin 5942e74eeadSLisandro Dalcin PetscFunctionBegin; /* v3 = v2 + A' * v1.*/ 595650997f4SStefano Zampini if (v3 != v2) { 596650997f4SStefano Zampini ierr = MatMultTranspose(A,v1,v3);CHKERRQ(ierr); 597650997f4SStefano Zampini ierr = VecAXPY(v3,1.0,v2);CHKERRQ(ierr); 598650997f4SStefano Zampini } else { 599650997f4SStefano Zampini ierr = VecDuplicate(v2,&temp_vec);CHKERRQ(ierr); 600650997f4SStefano Zampini ierr = MatMultTranspose(A,v1,temp_vec);CHKERRQ(ierr); 601650997f4SStefano Zampini ierr = VecAXPY(temp_vec,1.0,v2);CHKERRQ(ierr); 602650997f4SStefano Zampini ierr = VecCopy(temp_vec,v3);CHKERRQ(ierr); 603650997f4SStefano Zampini ierr = VecDestroy(&temp_vec);CHKERRQ(ierr); 604650997f4SStefano Zampini } 6052e74eeadSLisandro Dalcin PetscFunctionReturn(0); 6062e74eeadSLisandro Dalcin } 6072e74eeadSLisandro Dalcin 6082e74eeadSLisandro Dalcin #undef __FUNCT__ 609b4319ba4SBarry Smith #define __FUNCT__ "MatView_IS" 610dfbe8321SBarry Smith PetscErrorCode MatView_IS(Mat A,PetscViewer viewer) 611b4319ba4SBarry Smith { 612b4319ba4SBarry Smith Mat_IS *a = (Mat_IS*)A->data; 613dfbe8321SBarry Smith PetscErrorCode ierr; 614b4319ba4SBarry Smith PetscViewer sviewer; 615b4319ba4SBarry Smith 616b4319ba4SBarry Smith PetscFunctionBegin; 617dd2fa690SBarry Smith ierr = PetscViewerASCIISynchronizedAllow(viewer,PETSC_TRUE);CHKERRQ(ierr); 618b4319ba4SBarry Smith ierr = PetscViewerGetSingleton(viewer,&sviewer);CHKERRQ(ierr); 619b4319ba4SBarry Smith ierr = MatView(a->A,sviewer);CHKERRQ(ierr); 620b4319ba4SBarry Smith ierr = PetscViewerRestoreSingleton(viewer,&sviewer);CHKERRQ(ierr); 621b4319ba4SBarry Smith PetscFunctionReturn(0); 622b4319ba4SBarry Smith } 623b4319ba4SBarry Smith 624b4319ba4SBarry Smith #undef __FUNCT__ 625b4319ba4SBarry Smith #define __FUNCT__ "MatSetLocalToGlobalMapping_IS" 626784ac674SJed Brown PetscErrorCode MatSetLocalToGlobalMapping_IS(Mat A,ISLocalToGlobalMapping rmapping,ISLocalToGlobalMapping cmapping) 627b4319ba4SBarry Smith { 628dfbe8321SBarry Smith PetscErrorCode ierr; 6294e4c7dbeSStefano Zampini PetscInt n,bs; 630b4319ba4SBarry Smith Mat_IS *is = (Mat_IS*)A->data; 631b4319ba4SBarry Smith IS from,to; 632b4319ba4SBarry Smith Vec global; 633b4319ba4SBarry Smith 634b4319ba4SBarry Smith PetscFunctionBegin; 635784ac674SJed Brown PetscCheckSameComm(A,1,rmapping,2); 636ce94432eSBarry Smith if (rmapping != cmapping) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_INCOMP,"MATIS requires the row and column mappings to be identical"); 63770cf5478SStefano Zampini if (is->mapping) { /* Currenly destroys the objects that will be created by this routine. Is there anything else that should be checked? */ 63870cf5478SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&is->mapping);CHKERRQ(ierr); 63970cf5478SStefano Zampini ierr = VecDestroy(&is->x);CHKERRQ(ierr); 64070cf5478SStefano Zampini ierr = VecDestroy(&is->y);CHKERRQ(ierr); 64170cf5478SStefano Zampini ierr = VecScatterDestroy(&is->ctx);CHKERRQ(ierr); 6421c47cb0fSStefano Zampini ierr = MatDestroy(&is->A);CHKERRQ(ierr); 64328f4e0baSStefano Zampini ierr = PetscSFDestroy(&is->sf);CHKERRQ(ierr); 64428f4e0baSStefano Zampini ierr = PetscFree2(is->sf_rootdata,is->sf_leafdata);CHKERRQ(ierr); 64570cf5478SStefano Zampini } 646784ac674SJed Brown ierr = PetscObjectReference((PetscObject)rmapping);CHKERRQ(ierr); 6476bf464f9SBarry Smith ierr = ISLocalToGlobalMappingDestroy(&is->mapping);CHKERRQ(ierr); 648784ac674SJed Brown is->mapping = rmapping; 649fa7f1dd8SStefano Zampini /* 650fa7f1dd8SStefano Zampini ierr = PetscLayoutSetISLocalToGlobalMapping(A->rmap,rmapping);CHKERRQ(ierr); 651fa7f1dd8SStefano Zampini ierr = PetscLayoutSetISLocalToGlobalMapping(A->cmap,cmapping);CHKERRQ(ierr); 652fa7f1dd8SStefano Zampini */ 653b4319ba4SBarry Smith 654b4319ba4SBarry Smith /* Create the local matrix A */ 655784ac674SJed Brown ierr = ISLocalToGlobalMappingGetSize(rmapping,&n);CHKERRQ(ierr); 6562e1947a5SStefano Zampini ierr = ISLocalToGlobalMappingGetBlockSize(rmapping,&bs);CHKERRQ(ierr); 657f69a0ea3SMatthew Knepley ierr = MatCreate(PETSC_COMM_SELF,&is->A);CHKERRQ(ierr); 6582e1947a5SStefano Zampini if (bs > 1) { 6592e1947a5SStefano Zampini ierr = MatSetType(is->A,MATSEQBAIJ);CHKERRQ(ierr); 6602e1947a5SStefano Zampini } else { 6612e1947a5SStefano Zampini ierr = MatSetType(is->A,MATSEQAIJ);CHKERRQ(ierr); 6622e1947a5SStefano Zampini } 663f69a0ea3SMatthew Knepley ierr = MatSetSizes(is->A,n,n,n,n);CHKERRQ(ierr); 6644e4c7dbeSStefano Zampini ierr = MatSetBlockSize(is->A,bs);CHKERRQ(ierr); 665ff130e51SJed Brown ierr = MatSetOptionsPrefix(is->A,((PetscObject)A)->prefix);CHKERRQ(ierr); 666ff130e51SJed Brown ierr = MatAppendOptionsPrefix(is->A,"is_");CHKERRQ(ierr); 667b4319ba4SBarry Smith ierr = MatSetFromOptions(is->A);CHKERRQ(ierr); 668b4319ba4SBarry Smith 669b4319ba4SBarry Smith /* Create the local work vectors */ 6704e4c7dbeSStefano Zampini ierr = VecCreate(PETSC_COMM_SELF,&is->x);CHKERRQ(ierr); 6714e4c7dbeSStefano Zampini ierr = VecSetBlockSize(is->x,bs);CHKERRQ(ierr); 6724e4c7dbeSStefano Zampini ierr = VecSetSizes(is->x,n,n);CHKERRQ(ierr); 673ff130e51SJed Brown ierr = VecSetOptionsPrefix(is->x,((PetscObject)A)->prefix);CHKERRQ(ierr); 674ff130e51SJed Brown ierr = VecAppendOptionsPrefix(is->x,"is_");CHKERRQ(ierr); 6754e4c7dbeSStefano Zampini ierr = VecSetFromOptions(is->x);CHKERRQ(ierr); 676b4319ba4SBarry Smith ierr = VecDuplicate(is->x,&is->y);CHKERRQ(ierr); 677b4319ba4SBarry Smith 678b4319ba4SBarry Smith /* setup the global to local scatter */ 679b4319ba4SBarry Smith ierr = ISCreateStride(PETSC_COMM_SELF,n,0,1,&to);CHKERRQ(ierr); 680784ac674SJed Brown ierr = ISLocalToGlobalMappingApplyIS(rmapping,to,&from);CHKERRQ(ierr); 6812a7a6963SBarry Smith ierr = MatCreateVecs(A,&global,NULL);CHKERRQ(ierr); 682b4319ba4SBarry Smith ierr = VecScatterCreate(global,from,is->x,to,&is->ctx);CHKERRQ(ierr); 6836bf464f9SBarry Smith ierr = VecDestroy(&global);CHKERRQ(ierr); 6846bf464f9SBarry Smith ierr = ISDestroy(&to);CHKERRQ(ierr); 6856bf464f9SBarry Smith ierr = ISDestroy(&from);CHKERRQ(ierr); 686b4319ba4SBarry Smith PetscFunctionReturn(0); 687b4319ba4SBarry Smith } 688b4319ba4SBarry Smith 6892e74eeadSLisandro Dalcin #undef __FUNCT__ 6902e74eeadSLisandro Dalcin #define __FUNCT__ "MatSetValues_IS" 6912e74eeadSLisandro Dalcin PetscErrorCode MatSetValues_IS(Mat mat, PetscInt m,const PetscInt *rows, PetscInt n,const PetscInt *cols, const PetscScalar *values, InsertMode addv) 6922e74eeadSLisandro Dalcin { 6932e74eeadSLisandro Dalcin Mat_IS *is = (Mat_IS*)mat->data; 6942e74eeadSLisandro Dalcin PetscInt rows_l[2048],cols_l[2048]; 6952e74eeadSLisandro Dalcin PetscErrorCode ierr; 6962e74eeadSLisandro Dalcin 6972e74eeadSLisandro Dalcin PetscFunctionBegin; 6982e74eeadSLisandro Dalcin #if defined(PETSC_USE_DEBUG) 699f23aa3ddSBarry 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); 7002e74eeadSLisandro Dalcin #endif 7012e74eeadSLisandro Dalcin ierr = ISG2LMapApply(is->mapping,m,rows,rows_l);CHKERRQ(ierr); 7022e74eeadSLisandro Dalcin ierr = ISG2LMapApply(is->mapping,n,cols,cols_l);CHKERRQ(ierr); 7032e74eeadSLisandro Dalcin ierr = MatSetValues(is->A,m,rows_l,n,cols_l,values,addv);CHKERRQ(ierr); 7042e74eeadSLisandro Dalcin PetscFunctionReturn(0); 7052e74eeadSLisandro Dalcin } 7062e74eeadSLisandro Dalcin 7072e74eeadSLisandro Dalcin #undef ISG2LMapSetUp 7082e74eeadSLisandro Dalcin #undef ISG2LMapApply 709b4319ba4SBarry Smith 710b4319ba4SBarry Smith #undef __FUNCT__ 711b4319ba4SBarry Smith #define __FUNCT__ "MatSetValuesLocal_IS" 71213f74950SBarry Smith PetscErrorCode MatSetValuesLocal_IS(Mat A,PetscInt m,const PetscInt *rows, PetscInt n,const PetscInt *cols,const PetscScalar *values,InsertMode addv) 713b4319ba4SBarry Smith { 714dfbe8321SBarry Smith PetscErrorCode ierr; 715b4319ba4SBarry Smith Mat_IS *is = (Mat_IS*)A->data; 716b4319ba4SBarry Smith 717b4319ba4SBarry Smith PetscFunctionBegin; 718b4319ba4SBarry Smith ierr = MatSetValues(is->A,m,rows,n,cols,values,addv);CHKERRQ(ierr); 719b4319ba4SBarry Smith PetscFunctionReturn(0); 720b4319ba4SBarry Smith } 721b4319ba4SBarry Smith 722b4319ba4SBarry Smith #undef __FUNCT__ 723f0006bf2SLisandro Dalcin #define __FUNCT__ "MatSetValuesBlockedLocal_IS" 724f0006bf2SLisandro Dalcin PetscErrorCode MatSetValuesBlockedLocal_IS(Mat A,PetscInt m,const PetscInt *rows, PetscInt n,const PetscInt *cols,const PetscScalar *values,InsertMode addv) 725f0006bf2SLisandro Dalcin { 726f0006bf2SLisandro Dalcin PetscErrorCode ierr; 727f0006bf2SLisandro Dalcin Mat_IS *is = (Mat_IS*)A->data; 728f0006bf2SLisandro Dalcin 729f0006bf2SLisandro Dalcin PetscFunctionBegin; 730f0006bf2SLisandro Dalcin ierr = MatSetValuesBlocked(is->A,m,rows,n,cols,values,addv);CHKERRQ(ierr); 731f0006bf2SLisandro Dalcin PetscFunctionReturn(0); 732f0006bf2SLisandro Dalcin } 733f0006bf2SLisandro Dalcin 734f0006bf2SLisandro Dalcin #undef __FUNCT__ 7352e74eeadSLisandro Dalcin #define __FUNCT__ "MatZeroRows_IS" 7362b40b63fSBarry Smith PetscErrorCode MatZeroRows_IS(Mat A,PetscInt n,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 7372e74eeadSLisandro Dalcin { 7382e74eeadSLisandro Dalcin Mat_IS *is = (Mat_IS*)A->data; 7390298fd71SBarry Smith PetscInt n_l = 0, *rows_l = NULL; 7402e74eeadSLisandro Dalcin PetscErrorCode ierr; 7412e74eeadSLisandro Dalcin 7422e74eeadSLisandro Dalcin PetscFunctionBegin; 743ce94432eSBarry Smith if (x && b) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"No support"); 7442e74eeadSLisandro Dalcin if (n) { 745785e854fSJed Brown ierr = PetscMalloc1(n,&rows_l);CHKERRQ(ierr); 7462e74eeadSLisandro Dalcin ierr = ISGlobalToLocalMappingApply(is->mapping,IS_GTOLM_DROP,n,rows,&n_l,rows_l);CHKERRQ(ierr); 7472e74eeadSLisandro Dalcin } 7482b40b63fSBarry Smith ierr = MatZeroRowsLocal(A,n_l,rows_l,diag,x,b);CHKERRQ(ierr); 749c31cb41cSBarry Smith ierr = PetscFree(rows_l);CHKERRQ(ierr); 7502e74eeadSLisandro Dalcin PetscFunctionReturn(0); 7512e74eeadSLisandro Dalcin } 7522e74eeadSLisandro Dalcin 7532e74eeadSLisandro Dalcin #undef __FUNCT__ 754b4319ba4SBarry Smith #define __FUNCT__ "MatZeroRowsLocal_IS" 7552b40b63fSBarry Smith PetscErrorCode MatZeroRowsLocal_IS(Mat A,PetscInt n,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 756b4319ba4SBarry Smith { 757b4319ba4SBarry Smith Mat_IS *is = (Mat_IS*)A->data; 758dfbe8321SBarry Smith PetscErrorCode ierr; 759f4df32b1SMatthew Knepley PetscInt i; 760b4319ba4SBarry Smith PetscScalar *array; 761b4319ba4SBarry Smith 762b4319ba4SBarry Smith PetscFunctionBegin; 763ce94432eSBarry Smith if (x && b) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"No support"); 764b4319ba4SBarry Smith { 765b4319ba4SBarry Smith /* 766b4319ba4SBarry Smith Set up is->x as a "counting vector". This is in order to MatMult_IS 767b4319ba4SBarry Smith work properly in the interface nodes. 768b4319ba4SBarry Smith */ 769b4319ba4SBarry Smith Vec counter; 770b4319ba4SBarry Smith PetscScalar one=1.0, zero=0.0; 7712a7a6963SBarry Smith ierr = MatCreateVecs(A,&counter,NULL);CHKERRQ(ierr); 7722dcb1b2aSMatthew Knepley ierr = VecSet(counter,zero);CHKERRQ(ierr); 7732dcb1b2aSMatthew Knepley ierr = VecSet(is->x,one);CHKERRQ(ierr); 774ca9f406cSSatish Balay ierr = VecScatterBegin(is->ctx,is->x,counter,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 775ca9f406cSSatish Balay ierr = VecScatterEnd (is->ctx,is->x,counter,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 776ca9f406cSSatish Balay ierr = VecScatterBegin(is->ctx,counter,is->x,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 777ca9f406cSSatish Balay ierr = VecScatterEnd (is->ctx,counter,is->x,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 7786bf464f9SBarry Smith ierr = VecDestroy(&counter);CHKERRQ(ierr); 779b4319ba4SBarry Smith } 780958c9bccSBarry Smith if (!n) { 781b4319ba4SBarry Smith is->pure_neumann = PETSC_TRUE; 782b4319ba4SBarry Smith } else { 783b4319ba4SBarry Smith is->pure_neumann = PETSC_FALSE; 7842205254eSKarl Rupp 785b4319ba4SBarry Smith ierr = VecGetArray(is->x,&array);CHKERRQ(ierr); 7862b40b63fSBarry Smith ierr = MatZeroRows(is->A,n,rows,diag,0,0);CHKERRQ(ierr); 787b4319ba4SBarry Smith for (i=0; i<n; i++) { 788f4df32b1SMatthew Knepley ierr = MatSetValue(is->A,rows[i],rows[i],diag/(array[rows[i]]),INSERT_VALUES);CHKERRQ(ierr); 789b4319ba4SBarry Smith } 790b4319ba4SBarry Smith ierr = MatAssemblyBegin(is->A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 791b4319ba4SBarry Smith ierr = MatAssemblyEnd (is->A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 792b4319ba4SBarry Smith ierr = VecRestoreArray(is->x,&array);CHKERRQ(ierr); 793b4319ba4SBarry Smith } 794b4319ba4SBarry Smith PetscFunctionReturn(0); 795b4319ba4SBarry Smith } 796b4319ba4SBarry Smith 797b4319ba4SBarry Smith #undef __FUNCT__ 798b4319ba4SBarry Smith #define __FUNCT__ "MatAssemblyBegin_IS" 799dfbe8321SBarry Smith PetscErrorCode MatAssemblyBegin_IS(Mat A,MatAssemblyType type) 800b4319ba4SBarry Smith { 801b4319ba4SBarry Smith Mat_IS *is = (Mat_IS*)A->data; 802dfbe8321SBarry Smith PetscErrorCode ierr; 803b4319ba4SBarry Smith 804b4319ba4SBarry Smith PetscFunctionBegin; 805b4319ba4SBarry Smith ierr = MatAssemblyBegin(is->A,type);CHKERRQ(ierr); 806b4319ba4SBarry Smith PetscFunctionReturn(0); 807b4319ba4SBarry Smith } 808b4319ba4SBarry Smith 809b4319ba4SBarry Smith #undef __FUNCT__ 810b4319ba4SBarry Smith #define __FUNCT__ "MatAssemblyEnd_IS" 811dfbe8321SBarry Smith PetscErrorCode MatAssemblyEnd_IS(Mat A,MatAssemblyType type) 812b4319ba4SBarry Smith { 813b4319ba4SBarry Smith Mat_IS *is = (Mat_IS*)A->data; 814dfbe8321SBarry Smith PetscErrorCode ierr; 815b4319ba4SBarry Smith 816b4319ba4SBarry Smith PetscFunctionBegin; 817b4319ba4SBarry Smith ierr = MatAssemblyEnd(is->A,type);CHKERRQ(ierr); 818b4319ba4SBarry Smith PetscFunctionReturn(0); 819b4319ba4SBarry Smith } 820b4319ba4SBarry Smith 821b4319ba4SBarry Smith #undef __FUNCT__ 822b4319ba4SBarry Smith #define __FUNCT__ "MatISGetLocalMat_IS" 8237087cfbeSBarry Smith PetscErrorCode MatISGetLocalMat_IS(Mat mat,Mat *local) 824b4319ba4SBarry Smith { 825b4319ba4SBarry Smith Mat_IS *is = (Mat_IS*)mat->data; 826b4319ba4SBarry Smith 827b4319ba4SBarry Smith PetscFunctionBegin; 828b4319ba4SBarry Smith *local = is->A; 829b4319ba4SBarry Smith PetscFunctionReturn(0); 830b4319ba4SBarry Smith } 831b4319ba4SBarry Smith 832b4319ba4SBarry Smith #undef __FUNCT__ 833b4319ba4SBarry Smith #define __FUNCT__ "MatISGetLocalMat" 834b4319ba4SBarry Smith /*@ 835b4319ba4SBarry Smith MatISGetLocalMat - Gets the local matrix stored inside a MATIS matrix. 836b4319ba4SBarry Smith 837b4319ba4SBarry Smith Input Parameter: 838b4319ba4SBarry Smith . mat - the matrix 839b4319ba4SBarry Smith 840b4319ba4SBarry Smith Output Parameter: 841b4319ba4SBarry Smith . local - the local matrix usually MATSEQAIJ 842b4319ba4SBarry Smith 843b4319ba4SBarry Smith Level: advanced 844b4319ba4SBarry Smith 845b4319ba4SBarry Smith Notes: 846b4319ba4SBarry Smith This can be called if you have precomputed the nonzero structure of the 847b4319ba4SBarry Smith matrix and want to provide it to the inner matrix object to improve the performance 848b4319ba4SBarry Smith of the MatSetValues() operation. 849b4319ba4SBarry Smith 850b4319ba4SBarry Smith .seealso: MATIS 851b4319ba4SBarry Smith @*/ 8527087cfbeSBarry Smith PetscErrorCode MatISGetLocalMat(Mat mat,Mat *local) 853b4319ba4SBarry Smith { 8544ac538c5SBarry Smith PetscErrorCode ierr; 855b4319ba4SBarry Smith 856b4319ba4SBarry Smith PetscFunctionBegin; 8570700a824SBarry Smith PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 858b4319ba4SBarry Smith PetscValidPointer(local,2); 8594ac538c5SBarry Smith ierr = PetscUseMethod(mat,"MatISGetLocalMat_C",(Mat,Mat*),(mat,local));CHKERRQ(ierr); 860b4319ba4SBarry Smith PetscFunctionReturn(0); 861b4319ba4SBarry Smith } 862b4319ba4SBarry Smith 8633b03a366Sstefano_zampini #undef __FUNCT__ 8643b03a366Sstefano_zampini #define __FUNCT__ "MatISSetLocalMat_IS" 8653b03a366Sstefano_zampini PetscErrorCode MatISSetLocalMat_IS(Mat mat,Mat local) 8663b03a366Sstefano_zampini { 8673b03a366Sstefano_zampini Mat_IS *is = (Mat_IS*)mat->data; 8683b03a366Sstefano_zampini PetscInt nrows,ncols,orows,ocols; 8693b03a366Sstefano_zampini PetscErrorCode ierr; 8703b03a366Sstefano_zampini 8713b03a366Sstefano_zampini PetscFunctionBegin; 8724e4c7dbeSStefano Zampini if (is->A) { 8733b03a366Sstefano_zampini ierr = MatGetSize(is->A,&orows,&ocols);CHKERRQ(ierr); 8743b03a366Sstefano_zampini ierr = MatGetSize(local,&nrows,&ncols);CHKERRQ(ierr); 875f23aa3ddSBarry 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); 8764e4c7dbeSStefano Zampini } 8773b03a366Sstefano_zampini ierr = PetscObjectReference((PetscObject)local);CHKERRQ(ierr); 8783b03a366Sstefano_zampini ierr = MatDestroy(&is->A);CHKERRQ(ierr); 8793b03a366Sstefano_zampini is->A = local; 8803b03a366Sstefano_zampini PetscFunctionReturn(0); 8813b03a366Sstefano_zampini } 8823b03a366Sstefano_zampini 8833b03a366Sstefano_zampini #undef __FUNCT__ 8843b03a366Sstefano_zampini #define __FUNCT__ "MatISSetLocalMat" 8853b03a366Sstefano_zampini /*@ 8863b03a366Sstefano_zampini MatISSetLocalMat - Set the local matrix stored inside a MATIS matrix. 8873b03a366Sstefano_zampini 8883b03a366Sstefano_zampini Input Parameter: 8893b03a366Sstefano_zampini . mat - the matrix 8903b03a366Sstefano_zampini . local - the local matrix usually MATSEQAIJ 8913b03a366Sstefano_zampini 8923b03a366Sstefano_zampini Output Parameter: 8933b03a366Sstefano_zampini 8943b03a366Sstefano_zampini Level: advanced 8953b03a366Sstefano_zampini 8963b03a366Sstefano_zampini Notes: 8973b03a366Sstefano_zampini This can be called if you have precomputed the local matrix and 8983b03a366Sstefano_zampini want to provide it to the matrix object MATIS. 8993b03a366Sstefano_zampini 9003b03a366Sstefano_zampini .seealso: MATIS 9013b03a366Sstefano_zampini @*/ 9023b03a366Sstefano_zampini PetscErrorCode MatISSetLocalMat(Mat mat,Mat local) 9033b03a366Sstefano_zampini { 9043b03a366Sstefano_zampini PetscErrorCode ierr; 9053b03a366Sstefano_zampini 9063b03a366Sstefano_zampini PetscFunctionBegin; 9073b03a366Sstefano_zampini PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 908b7ce53b6SStefano Zampini PetscValidHeaderSpecific(local,MAT_CLASSID,2); 9093b03a366Sstefano_zampini ierr = PetscUseMethod(mat,"MatISSetLocalMat_C",(Mat,Mat),(mat,local));CHKERRQ(ierr); 9103b03a366Sstefano_zampini PetscFunctionReturn(0); 9113b03a366Sstefano_zampini } 9123b03a366Sstefano_zampini 9136726f965SBarry Smith #undef __FUNCT__ 9146726f965SBarry Smith #define __FUNCT__ "MatZeroEntries_IS" 9156726f965SBarry Smith PetscErrorCode MatZeroEntries_IS(Mat A) 9166726f965SBarry Smith { 9176726f965SBarry Smith Mat_IS *a = (Mat_IS*)A->data; 9186726f965SBarry Smith PetscErrorCode ierr; 9196726f965SBarry Smith 9206726f965SBarry Smith PetscFunctionBegin; 9216726f965SBarry Smith ierr = MatZeroEntries(a->A);CHKERRQ(ierr); 9226726f965SBarry Smith PetscFunctionReturn(0); 9236726f965SBarry Smith } 9246726f965SBarry Smith 9256726f965SBarry Smith #undef __FUNCT__ 9262e74eeadSLisandro Dalcin #define __FUNCT__ "MatScale_IS" 9272e74eeadSLisandro Dalcin PetscErrorCode MatScale_IS(Mat A,PetscScalar a) 9282e74eeadSLisandro Dalcin { 9292e74eeadSLisandro Dalcin Mat_IS *is = (Mat_IS*)A->data; 9302e74eeadSLisandro Dalcin PetscErrorCode ierr; 9312e74eeadSLisandro Dalcin 9322e74eeadSLisandro Dalcin PetscFunctionBegin; 9332e74eeadSLisandro Dalcin ierr = MatScale(is->A,a);CHKERRQ(ierr); 9342e74eeadSLisandro Dalcin PetscFunctionReturn(0); 9352e74eeadSLisandro Dalcin } 9362e74eeadSLisandro Dalcin 9372e74eeadSLisandro Dalcin #undef __FUNCT__ 9382e74eeadSLisandro Dalcin #define __FUNCT__ "MatGetDiagonal_IS" 9392e74eeadSLisandro Dalcin PetscErrorCode MatGetDiagonal_IS(Mat A, Vec v) 9402e74eeadSLisandro Dalcin { 9412e74eeadSLisandro Dalcin Mat_IS *is = (Mat_IS*)A->data; 9422e74eeadSLisandro Dalcin PetscErrorCode ierr; 9432e74eeadSLisandro Dalcin 9442e74eeadSLisandro Dalcin PetscFunctionBegin; 9452e74eeadSLisandro Dalcin /* get diagonal of the local matrix */ 9462e74eeadSLisandro Dalcin ierr = MatGetDiagonal(is->A,is->x);CHKERRQ(ierr); 9472e74eeadSLisandro Dalcin 9482e74eeadSLisandro Dalcin /* scatter diagonal back into global vector */ 9492e74eeadSLisandro Dalcin ierr = VecSet(v,0);CHKERRQ(ierr); 950ca9f406cSSatish Balay ierr = VecScatterBegin(is->ctx,is->x,v,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 951ca9f406cSSatish Balay ierr = VecScatterEnd (is->ctx,is->x,v,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 9522e74eeadSLisandro Dalcin PetscFunctionReturn(0); 9532e74eeadSLisandro Dalcin } 9542e74eeadSLisandro Dalcin 9552e74eeadSLisandro Dalcin #undef __FUNCT__ 9566726f965SBarry Smith #define __FUNCT__ "MatSetOption_IS" 957ace3abfcSBarry Smith PetscErrorCode MatSetOption_IS(Mat A,MatOption op,PetscBool flg) 9586726f965SBarry Smith { 9596726f965SBarry Smith Mat_IS *a = (Mat_IS*)A->data; 9606726f965SBarry Smith PetscErrorCode ierr; 9616726f965SBarry Smith 9626726f965SBarry Smith PetscFunctionBegin; 9634e0d8c25SBarry Smith ierr = MatSetOption(a->A,op,flg);CHKERRQ(ierr); 9646726f965SBarry Smith PetscFunctionReturn(0); 9656726f965SBarry Smith } 9666726f965SBarry Smith 967284134d9SBarry Smith #undef __FUNCT__ 968284134d9SBarry Smith #define __FUNCT__ "MatCreateIS" 969284134d9SBarry Smith /*@ 970284134d9SBarry Smith MatCreateIS - Creates a "process" unassmembled matrix, it is assembled on each 971284134d9SBarry Smith process but not across processes. 972284134d9SBarry Smith 973284134d9SBarry Smith Input Parameters: 974284134d9SBarry Smith + comm - MPI communicator that will share the matrix 9754e4c7dbeSStefano Zampini . bs - local and global block size of the matrix 976df3898eeSBarry Smith . m,n,M,N - local and/or global sizes of the left and right vector used in matrix vector products 977284134d9SBarry Smith - map - mapping that defines the global number for each local number 978284134d9SBarry Smith 979284134d9SBarry Smith Output Parameter: 980284134d9SBarry Smith . A - the resulting matrix 981284134d9SBarry Smith 9828e6c10adSSatish Balay Level: advanced 9838e6c10adSSatish Balay 984284134d9SBarry Smith Notes: See MATIS for more details 9858cda6cd7SBarry Smith m and n are NOT related to the size of the map, they are the size of the part of the vector owned 9868cda6cd7SBarry Smith by that process. m + nghosts (or n + nghosts) is the length of map since map maps all local points 9878cda6cd7SBarry Smith plus the ghost points to global indices. 988284134d9SBarry Smith 989284134d9SBarry Smith .seealso: MATIS, MatSetLocalToGlobalMapping() 990284134d9SBarry Smith @*/ 9914e4c7dbeSStefano Zampini PetscErrorCode MatCreateIS(MPI_Comm comm,PetscInt bs,PetscInt m,PetscInt n,PetscInt M,PetscInt N,ISLocalToGlobalMapping map,Mat *A) 992284134d9SBarry Smith { 993284134d9SBarry Smith PetscErrorCode ierr; 994284134d9SBarry Smith 995284134d9SBarry Smith PetscFunctionBegin; 996284134d9SBarry Smith ierr = MatCreate(comm,A);CHKERRQ(ierr); 997d3ee2243SStefano Zampini ierr = MatSetBlockSize(*A,bs);CHKERRQ(ierr); 998284134d9SBarry Smith ierr = MatSetSizes(*A,m,n,M,N);CHKERRQ(ierr); 999284134d9SBarry Smith ierr = MatSetType(*A,MATIS);CHKERRQ(ierr); 10003b03a366Sstefano_zampini ierr = MatSetUp(*A);CHKERRQ(ierr); 1001784ac674SJed Brown ierr = MatSetLocalToGlobalMapping(*A,map,map);CHKERRQ(ierr); 1002284134d9SBarry Smith PetscFunctionReturn(0); 1003284134d9SBarry Smith } 1004284134d9SBarry Smith 1005b4319ba4SBarry Smith /*MC 10066a818285SBarry Smith MATIS - MATIS = "is" - A matrix type to be used for using the Neumann-Neumann type preconditioners, see PCBDDC. 1007b4319ba4SBarry Smith This stores the matrices in globally unassembled form. Each processor 1008b4319ba4SBarry Smith assembles only its local Neumann problem and the parallel matrix vector 1009b4319ba4SBarry Smith product is handled "implicitly". 1010b4319ba4SBarry Smith 1011b4319ba4SBarry Smith Operations Provided: 10126726f965SBarry Smith + MatMult() 10132e74eeadSLisandro Dalcin . MatMultAdd() 10142e74eeadSLisandro Dalcin . MatMultTranspose() 10152e74eeadSLisandro Dalcin . MatMultTransposeAdd() 10166726f965SBarry Smith . MatZeroEntries() 10176726f965SBarry Smith . MatSetOption() 10182e74eeadSLisandro Dalcin . MatZeroRows() 10196726f965SBarry Smith . MatZeroRowsLocal() 10202e74eeadSLisandro Dalcin . MatSetValues() 10216726f965SBarry Smith . MatSetValuesLocal() 10222e74eeadSLisandro Dalcin . MatScale() 10232e74eeadSLisandro Dalcin . MatGetDiagonal() 10246726f965SBarry Smith - MatSetLocalToGlobalMapping() 1025b4319ba4SBarry Smith 1026b4319ba4SBarry Smith Options Database Keys: 1027b4319ba4SBarry Smith . -mat_type is - sets the matrix type to "is" during a call to MatSetFromOptions() 1028b4319ba4SBarry Smith 1029b4319ba4SBarry Smith Notes: Options prefix for the inner matrix are given by -is_mat_xxx 1030b4319ba4SBarry Smith 1031b4319ba4SBarry Smith You must call MatSetLocalToGlobalMapping() before using this matrix type. 1032b4319ba4SBarry Smith 1033b4319ba4SBarry Smith You can do matrix preallocation on the local matrix after you obtain it with 1034b4319ba4SBarry Smith MatISGetLocalMat() 1035b4319ba4SBarry Smith 1036b4319ba4SBarry Smith Level: advanced 1037b4319ba4SBarry Smith 10386a818285SBarry Smith .seealso: PC, MatISGetLocalMat(), MatSetLocalToGlobalMapping(), PCBDDC 1039b4319ba4SBarry Smith 1040b4319ba4SBarry Smith M*/ 1041b4319ba4SBarry Smith 1042b4319ba4SBarry Smith #undef __FUNCT__ 1043b4319ba4SBarry Smith #define __FUNCT__ "MatCreate_IS" 10448cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatCreate_IS(Mat A) 1045b4319ba4SBarry Smith { 1046dfbe8321SBarry Smith PetscErrorCode ierr; 1047b4319ba4SBarry Smith Mat_IS *b; 1048b4319ba4SBarry Smith 1049b4319ba4SBarry Smith PetscFunctionBegin; 1050b00a9115SJed Brown ierr = PetscNewLog(A,&b);CHKERRQ(ierr); 1051b4319ba4SBarry Smith A->data = (void*)b; 1052b4319ba4SBarry Smith ierr = PetscMemzero(A->ops,sizeof(struct _MatOps));CHKERRQ(ierr); 1053b4319ba4SBarry Smith 1054b4319ba4SBarry Smith A->ops->mult = MatMult_IS; 10552e74eeadSLisandro Dalcin A->ops->multadd = MatMultAdd_IS; 10562e74eeadSLisandro Dalcin A->ops->multtranspose = MatMultTranspose_IS; 10572e74eeadSLisandro Dalcin A->ops->multtransposeadd = MatMultTransposeAdd_IS; 1058b4319ba4SBarry Smith A->ops->destroy = MatDestroy_IS; 1059b4319ba4SBarry Smith A->ops->setlocaltoglobalmapping = MatSetLocalToGlobalMapping_IS; 10602e74eeadSLisandro Dalcin A->ops->setvalues = MatSetValues_IS; 1061b4319ba4SBarry Smith A->ops->setvalueslocal = MatSetValuesLocal_IS; 1062f0006bf2SLisandro Dalcin A->ops->setvaluesblockedlocal = MatSetValuesBlockedLocal_IS; 10632e74eeadSLisandro Dalcin A->ops->zerorows = MatZeroRows_IS; 1064b4319ba4SBarry Smith A->ops->zerorowslocal = MatZeroRowsLocal_IS; 1065b4319ba4SBarry Smith A->ops->assemblybegin = MatAssemblyBegin_IS; 1066b4319ba4SBarry Smith A->ops->assemblyend = MatAssemblyEnd_IS; 1067b4319ba4SBarry Smith A->ops->view = MatView_IS; 10686726f965SBarry Smith A->ops->zeroentries = MatZeroEntries_IS; 10692e74eeadSLisandro Dalcin A->ops->scale = MatScale_IS; 10702e74eeadSLisandro Dalcin A->ops->getdiagonal = MatGetDiagonal_IS; 10716726f965SBarry Smith A->ops->setoption = MatSetOption_IS; 107269796d55SStefano Zampini A->ops->ishermitian = MatIsHermitian_IS; 107369796d55SStefano Zampini A->ops->issymmetric = MatIsSymmetric_IS; 1074ad6194a2SStefano Zampini A->ops->duplicate = MatDuplicate_IS; 1075b4319ba4SBarry Smith 107626283091SBarry Smith ierr = PetscLayoutSetUp(A->rmap);CHKERRQ(ierr); 107726283091SBarry Smith ierr = PetscLayoutSetUp(A->cmap);CHKERRQ(ierr); 1078b4319ba4SBarry Smith 1079b7ce53b6SStefano Zampini /* zeros pointer */ 1080b4319ba4SBarry Smith b->A = 0; 1081b4319ba4SBarry Smith b->ctx = 0; 1082b4319ba4SBarry Smith b->x = 0; 1083b4319ba4SBarry Smith b->y = 0; 1084b09366fdSStefano Zampini b->mapping = 0; 108528f4e0baSStefano Zampini b->sf = 0; 108628f4e0baSStefano Zampini b->sf_rootdata = 0; 108728f4e0baSStefano Zampini b->sf_leafdata = 0; 1088b7ce53b6SStefano Zampini 1089b7ce53b6SStefano Zampini /* special MATIS functions */ 1090bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatISGetLocalMat_C",MatISGetLocalMat_IS);CHKERRQ(ierr); 1091bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatISSetLocalMat_C",MatISSetLocalMat_IS);CHKERRQ(ierr); 1092b7ce53b6SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatISGetMPIXAIJ_C",MatISGetMPIXAIJ_IS);CHKERRQ(ierr); 10932e1947a5SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatISSetPreallocation_C",MatISSetPreallocation_IS);CHKERRQ(ierr); 109417667f90SBarry Smith ierr = PetscObjectChangeTypeName((PetscObject)A,MATIS);CHKERRQ(ierr); 1095b4319ba4SBarry Smith PetscFunctionReturn(0); 1096b4319ba4SBarry Smith } 1097