1be1d678aSKris Buschelman #define PETSCMAT_DLL 26f79c3a4SBarry Smith 37c4f633dSBarry Smith #include "private/matimpl.h" /*I "petscmat.h" I*/ 46f79c3a4SBarry Smith 54a2ae208SSatish Balay #undef __FUNCT__ 64a2ae208SSatish Balay #define __FUNCT__ "MatAXPY" 706be10caSBarry Smith /*@ 821c89e3eSBarry Smith MatAXPY - Computes Y = a*X + Y. 96f79c3a4SBarry Smith 10fee21e36SBarry Smith Collective on Mat 11fee21e36SBarry Smith 1298a79cdbSBarry Smith Input Parameters: 13607cd303SBarry Smith + a - the scalar multiplier 14607cd303SBarry Smith . X - the first matrix 15607cd303SBarry Smith . Y - the second matrix 16407f6b05SHong Zhang - str - either SAME_NONZERO_PATTERN, DIFFERENT_NONZERO_PATTERN 17407f6b05SHong Zhang or SUBSET_NONZERO_PATTERN (nonzeros of X is a subset of Y's) 1898a79cdbSBarry Smith 192860a424SLois Curfman McInnes Notes: 201a5ee19eSHong Zhang Will only be efficient if one has the SAME_NONZERO_PATTERN or SUBSET_NONZERO_PATTERN 212860a424SLois Curfman McInnes 222860a424SLois Curfman McInnes Level: intermediate 232860a424SLois Curfman McInnes 249cf4f1e8SLois Curfman McInnes .keywords: matrix, add 25d4bb536fSBarry Smith 262860a424SLois Curfman McInnes .seealso: MatAYPX() 2706be10caSBarry Smith @*/ 28f4df32b1SMatthew Knepley PetscErrorCode PETSCMAT_DLLEXPORT MatAXPY(Mat Y,PetscScalar a,Mat X,MatStructure str) 296f79c3a4SBarry Smith { 306849ba73SBarry Smith PetscErrorCode ierr; 31c1ac3661SBarry Smith PetscInt m1,m2,n1,n2; 326f79c3a4SBarry Smith 333a40ed3dSBarry Smith PetscFunctionBegin; 34*0700a824SBarry Smith PetscValidHeaderSpecific(X,MAT_CLASSID,3); 35*0700a824SBarry Smith PetscValidHeaderSpecific(Y,MAT_CLASSID,1); 3690f02eecSBarry Smith 37273d9f13SBarry Smith ierr = MatGetSize(X,&m1,&n1);CHKERRQ(ierr); 38273d9f13SBarry Smith ierr = MatGetSize(Y,&m2,&n2);CHKERRQ(ierr); 3977431f27SBarry Smith if (m1 != m2 || n1 != n2) SETERRQ4(PETSC_ERR_ARG_SIZ,"Non conforming matrix add: %D %D %D %D",m1,m2,n1,n2); 401987afe7SBarry Smith 41f4df32b1SMatthew Knepley if (Y->ops->axpy) { 42f4df32b1SMatthew Knepley ierr = (*Y->ops->axpy)(Y,a,X,str);CHKERRQ(ierr); 43d4bb536fSBarry Smith } else { 44f4df32b1SMatthew Knepley ierr = MatAXPY_Basic(Y,a,X,str);CHKERRQ(ierr); 45607cd303SBarry Smith } 46607cd303SBarry Smith PetscFunctionReturn(0); 47607cd303SBarry Smith } 48607cd303SBarry Smith 49607cd303SBarry Smith 50607cd303SBarry Smith #undef __FUNCT__ 51607cd303SBarry Smith #define __FUNCT__ "MatAXPY_Basic" 52f4df32b1SMatthew Knepley PetscErrorCode MatAXPY_Basic(Mat Y,PetscScalar a,Mat X,MatStructure str) 53607cd303SBarry Smith { 5438baddfdSBarry Smith PetscInt i,start,end,j,ncols,m,n; 556849ba73SBarry Smith PetscErrorCode ierr; 5638baddfdSBarry Smith const PetscInt *row; 57b3cc6726SBarry Smith PetscScalar *val; 58b3cc6726SBarry Smith const PetscScalar *vals; 59607cd303SBarry Smith 60607cd303SBarry Smith PetscFunctionBegin; 618dadbd76SSatish Balay ierr = MatGetSize(X,&m,&n);CHKERRQ(ierr); 6290f02eecSBarry Smith ierr = MatGetOwnershipRange(X,&start,&end);CHKERRQ(ierr); 63f4df32b1SMatthew Knepley if (a == 1.0) { 64d4bb536fSBarry Smith for (i = start; i < end; i++) { 65d4bb536fSBarry Smith ierr = MatGetRow(X,i,&ncols,&row,&vals);CHKERRQ(ierr); 66d4bb536fSBarry Smith ierr = MatSetValues(Y,1,&i,ncols,row,vals,ADD_VALUES);CHKERRQ(ierr); 67d4bb536fSBarry Smith ierr = MatRestoreRow(X,i,&ncols,&row,&vals);CHKERRQ(ierr); 68d4bb536fSBarry Smith } 69d4bb536fSBarry Smith } else { 70b3cc6726SBarry Smith ierr = PetscMalloc((n+1)*sizeof(PetscScalar),&val);CHKERRQ(ierr); 7106be10caSBarry Smith for (i=start; i<end; i++) { 72b3cc6726SBarry Smith ierr = MatGetRow(X,i,&ncols,&row,&vals);CHKERRQ(ierr); 7306be10caSBarry Smith for (j=0; j<ncols; j++) { 74f4df32b1SMatthew Knepley val[j] = a*vals[j]; 756f79c3a4SBarry Smith } 76b3cc6726SBarry Smith ierr = MatSetValues(Y,1,&i,ncols,row,val,ADD_VALUES);CHKERRQ(ierr); 77b3cc6726SBarry Smith ierr = MatRestoreRow(X,i,&ncols,&row,&vals);CHKERRQ(ierr); 786f79c3a4SBarry Smith } 79b3cc6726SBarry Smith ierr = PetscFree(val);CHKERRQ(ierr); 80d4bb536fSBarry Smith } 816d4a8577SBarry Smith ierr = MatAssemblyBegin(Y,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 826d4a8577SBarry Smith ierr = MatAssemblyEnd(Y,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 833a40ed3dSBarry Smith PetscFunctionReturn(0); 846f79c3a4SBarry Smith } 85052efed2SBarry Smith 864a2ae208SSatish Balay #undef __FUNCT__ 874a2ae208SSatish Balay #define __FUNCT__ "MatShift" 88052efed2SBarry Smith /*@ 8987828ca2SBarry Smith MatShift - Computes Y = Y + a I, where a is a PetscScalar and I is the identity matrix. 90052efed2SBarry Smith 91fee21e36SBarry Smith Collective on Mat 92fee21e36SBarry Smith 9398a79cdbSBarry Smith Input Parameters: 9498a79cdbSBarry Smith + Y - the matrices 9587828ca2SBarry Smith - a - the PetscScalar 9698a79cdbSBarry Smith 972860a424SLois Curfman McInnes Level: intermediate 982860a424SLois Curfman McInnes 99052efed2SBarry Smith .keywords: matrix, add, shift 1006b9ee512SLois Curfman McInnes 101f56f2b3fSBarry Smith .seealso: MatDiagonalSet() 102052efed2SBarry Smith @*/ 103f4df32b1SMatthew Knepley PetscErrorCode PETSCMAT_DLLEXPORT MatShift(Mat Y,PetscScalar a) 104052efed2SBarry Smith { 1056849ba73SBarry Smith PetscErrorCode ierr; 10638baddfdSBarry Smith PetscInt i,start,end; 107052efed2SBarry Smith 1083a40ed3dSBarry Smith PetscFunctionBegin; 109*0700a824SBarry Smith PetscValidHeaderSpecific(Y,MAT_CLASSID,1); 11032dfb669SBarry Smith if (!Y->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 111d5f3da31SBarry Smith if (Y->factortype) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 112b50b34bdSBarry Smith ierr = MatPreallocated(Y);CHKERRQ(ierr); 113b50b34bdSBarry Smith 114f830108cSBarry Smith if (Y->ops->shift) { 115f4df32b1SMatthew Knepley ierr = (*Y->ops->shift)(Y,a);CHKERRQ(ierr); 11662d58ce1SBarry Smith } else { 117f4df32b1SMatthew Knepley PetscScalar alpha = a; 118d4bb536fSBarry Smith ierr = MatGetOwnershipRange(Y,&start,&end);CHKERRQ(ierr); 119052efed2SBarry Smith for (i=start; i<end; i++) { 120f4df32b1SMatthew Knepley ierr = MatSetValues(Y,1,&i,1,&i,&alpha,ADD_VALUES);CHKERRQ(ierr); 121052efed2SBarry Smith } 1226d4a8577SBarry Smith ierr = MatAssemblyBegin(Y,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1236d4a8577SBarry Smith ierr = MatAssemblyEnd(Y,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 124052efed2SBarry Smith } 1253a40ed3dSBarry Smith PetscFunctionReturn(0); 126052efed2SBarry Smith } 1276d84be18SBarry Smith 1284a2ae208SSatish Balay #undef __FUNCT__ 12909f38230SBarry Smith #define __FUNCT__ "MatDiagonalSet_Default" 13009f38230SBarry Smith PetscErrorCode PETSCMAT_DLLEXPORT MatDiagonalSet_Default(Mat Y,Vec D,InsertMode is) 13109f38230SBarry Smith { 13209f38230SBarry Smith PetscErrorCode ierr; 13309f38230SBarry Smith PetscInt i,start,end,vstart,vend; 13409f38230SBarry Smith PetscScalar *v; 13509f38230SBarry Smith 13609f38230SBarry Smith PetscFunctionBegin; 13709f38230SBarry Smith ierr = VecGetOwnershipRange(D,&vstart,&vend);CHKERRQ(ierr); 13809f38230SBarry Smith ierr = MatGetOwnershipRange(Y,&start,&end);CHKERRQ(ierr); 13909f38230SBarry Smith if (vstart != start || vend != end) { 14009f38230SBarry Smith SETERRQ4(PETSC_ERR_ARG_SIZ,"Vector ownership range not compatible with matrix: %D %D vec %D %D mat",vstart,vend,start,end); 14109f38230SBarry Smith } 14209f38230SBarry Smith ierr = VecGetArray(D,&v);CHKERRQ(ierr); 14309f38230SBarry Smith for (i=start; i<end; i++) { 14409f38230SBarry Smith ierr = MatSetValues(Y,1,&i,1,&i,v+i-start,is);CHKERRQ(ierr); 14509f38230SBarry Smith } 14609f38230SBarry Smith ierr = VecRestoreArray(D,&v);CHKERRQ(ierr); 14709f38230SBarry Smith ierr = MatAssemblyBegin(Y,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 14809f38230SBarry Smith ierr = MatAssemblyEnd(Y,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 14909f38230SBarry Smith PetscFunctionReturn(0); 15009f38230SBarry Smith } 15109f38230SBarry Smith 15209f38230SBarry Smith #undef __FUNCT__ 1534a2ae208SSatish Balay #define __FUNCT__ "MatDiagonalSet" 1546d84be18SBarry Smith /*@ 155f56f2b3fSBarry Smith MatDiagonalSet - Computes Y = Y + D, where D is a diagonal matrix 156f56f2b3fSBarry Smith that is represented as a vector. Or Y[i,i] = D[i] if InsertMode is 157f56f2b3fSBarry Smith INSERT_VALUES. 1586d84be18SBarry Smith 1596d84be18SBarry Smith Input Parameters: 16098a79cdbSBarry Smith + Y - the input matrix 161f56f2b3fSBarry Smith . D - the diagonal matrix, represented as a vector 162f56f2b3fSBarry Smith - i - INSERT_VALUES or ADD_VALUES 1636d84be18SBarry Smith 164fee21e36SBarry Smith Collective on Mat and Vec 165fee21e36SBarry Smith 1662860a424SLois Curfman McInnes Level: intermediate 1672860a424SLois Curfman McInnes 1686b9ee512SLois Curfman McInnes .keywords: matrix, add, shift, diagonal 1696b9ee512SLois Curfman McInnes 1706b9ee512SLois Curfman McInnes .seealso: MatShift() 1716d84be18SBarry Smith @*/ 172be1d678aSKris Buschelman PetscErrorCode PETSCMAT_DLLEXPORT MatDiagonalSet(Mat Y,Vec D,InsertMode is) 1736d84be18SBarry Smith { 1746849ba73SBarry Smith PetscErrorCode ierr; 1756d84be18SBarry Smith 1763a40ed3dSBarry Smith PetscFunctionBegin; 177*0700a824SBarry Smith PetscValidHeaderSpecific(Y,MAT_CLASSID,1); 178*0700a824SBarry Smith PetscValidHeaderSpecific(D,VEC_CLASSID,2); 179f56f2b3fSBarry Smith if (Y->ops->diagonalset) { 180f56f2b3fSBarry Smith ierr = (*Y->ops->diagonalset)(Y,D,is);CHKERRQ(ierr); 18194d884c6SBarry Smith } else { 18209f38230SBarry Smith ierr = MatDiagonalSet_Default(Y,D,is);CHKERRQ(ierr); 1836d84be18SBarry Smith } 1843a40ed3dSBarry Smith PetscFunctionReturn(0); 1856d84be18SBarry Smith } 186d4bb536fSBarry Smith 1874a2ae208SSatish Balay #undef __FUNCT__ 1884a2ae208SSatish Balay #define __FUNCT__ "MatAYPX" 189d4bb536fSBarry Smith /*@ 19004aac2b0SHong Zhang MatAYPX - Computes Y = a*Y + X. 191d4bb536fSBarry Smith 192fee21e36SBarry Smith Collective on Mat 193fee21e36SBarry Smith 19498a79cdbSBarry Smith Input Parameters: 19504aac2b0SHong Zhang + a - the PetscScalar multiplier 19604aac2b0SHong Zhang . Y - the first matrix 19704aac2b0SHong Zhang . X - the second matrix 19804aac2b0SHong Zhang - str - either SAME_NONZERO_PATTERN, DIFFERENT_NONZERO_PATTERN or SUBSET_NONZERO_PATTERN 199d4bb536fSBarry Smith 2002860a424SLois Curfman McInnes Notes: 20104aac2b0SHong Zhang Will only be efficient if one has the SAME_NONZERO_PATTERN or SUBSET_NONZERO_PATTERN 202607cd303SBarry Smith 2032860a424SLois Curfman McInnes Level: intermediate 2042860a424SLois Curfman McInnes 205d4bb536fSBarry Smith .keywords: matrix, add 206d4bb536fSBarry Smith 2072860a424SLois Curfman McInnes .seealso: MatAXPY() 208d4bb536fSBarry Smith @*/ 20904aac2b0SHong Zhang PetscErrorCode PETSCMAT_DLLEXPORT MatAYPX(Mat Y,PetscScalar a,Mat X,MatStructure str) 210d4bb536fSBarry Smith { 21187828ca2SBarry Smith PetscScalar one = 1.0; 2126849ba73SBarry Smith PetscErrorCode ierr; 21338baddfdSBarry Smith PetscInt mX,mY,nX,nY; 214d4bb536fSBarry Smith 2153a40ed3dSBarry Smith PetscFunctionBegin; 216*0700a824SBarry Smith PetscValidHeaderSpecific(X,MAT_CLASSID,2); 217*0700a824SBarry Smith PetscValidHeaderSpecific(Y,MAT_CLASSID,1); 218d4bb536fSBarry Smith 219329f5518SBarry Smith ierr = MatGetSize(X,&mX,&nX);CHKERRQ(ierr); 220329f5518SBarry Smith ierr = MatGetSize(X,&mY,&nY);CHKERRQ(ierr); 22177431f27SBarry Smith if (mX != mY || nX != nY) SETERRQ4(PETSC_ERR_ARG_SIZ,"Non conforming matrices: %D %D first %D %D second",mX,mY,nX,nY); 222d4bb536fSBarry Smith 223f4df32b1SMatthew Knepley ierr = MatScale(Y,a);CHKERRQ(ierr); 22404aac2b0SHong Zhang ierr = MatAXPY(Y,one,X,str);CHKERRQ(ierr) 2253a40ed3dSBarry Smith PetscFunctionReturn(0); 226d4bb536fSBarry Smith } 227b0a32e0cSBarry Smith 2284a2ae208SSatish Balay #undef __FUNCT__ 2294a2ae208SSatish Balay #define __FUNCT__ "MatComputeExplicitOperator" 230b0a32e0cSBarry Smith /*@ 231b0a32e0cSBarry Smith MatComputeExplicitOperator - Computes the explicit matrix 232b0a32e0cSBarry Smith 233b0a32e0cSBarry Smith Collective on Mat 234b0a32e0cSBarry Smith 235b0a32e0cSBarry Smith Input Parameter: 236b0a32e0cSBarry Smith . inmat - the matrix 237b0a32e0cSBarry Smith 238b0a32e0cSBarry Smith Output Parameter: 239b0a32e0cSBarry Smith . mat - the explict preconditioned operator 240b0a32e0cSBarry Smith 241b0a32e0cSBarry Smith Notes: 242b0a32e0cSBarry Smith This computation is done by applying the operators to columns of the 243b0a32e0cSBarry Smith identity matrix. 244b0a32e0cSBarry Smith 245b0a32e0cSBarry Smith Currently, this routine uses a dense matrix format when 1 processor 246b0a32e0cSBarry Smith is used and a sparse format otherwise. This routine is costly in general, 247b0a32e0cSBarry Smith and is recommended for use only with relatively small systems. 248b0a32e0cSBarry Smith 249b0a32e0cSBarry Smith Level: advanced 250b0a32e0cSBarry Smith 251b0a32e0cSBarry Smith .keywords: Mat, compute, explicit, operator 252b0a32e0cSBarry Smith 253b0a32e0cSBarry Smith @*/ 254be1d678aSKris Buschelman PetscErrorCode PETSCMAT_DLLEXPORT MatComputeExplicitOperator(Mat inmat,Mat *mat) 255b0a32e0cSBarry Smith { 256b0a32e0cSBarry Smith Vec in,out; 257dfbe8321SBarry Smith PetscErrorCode ierr; 2580b12b109SJed Brown PetscInt i,m,n,M,N,*rows,start,end; 259b0a32e0cSBarry Smith MPI_Comm comm; 26087828ca2SBarry Smith PetscScalar *array,zero = 0.0,one = 1.0; 26138baddfdSBarry Smith PetscMPIInt size; 262b0a32e0cSBarry Smith 263b0a32e0cSBarry Smith PetscFunctionBegin; 264*0700a824SBarry Smith PetscValidHeaderSpecific(inmat,MAT_CLASSID,1); 2654482741eSBarry Smith PetscValidPointer(mat,2); 266b0a32e0cSBarry Smith 2677adad957SLisandro Dalcin comm = ((PetscObject)inmat)->comm; 268b0a32e0cSBarry Smith ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 269b0a32e0cSBarry Smith 2700b12b109SJed Brown ierr = MatGetLocalSize(inmat,&m,&n);CHKERRQ(ierr); 2710b12b109SJed Brown ierr = MatGetSize(inmat,&M,&N);CHKERRQ(ierr); 2720b12b109SJed Brown ierr = MatGetVecs(inmat,&in,&out);CHKERRQ(ierr); 2730b12b109SJed Brown ierr = VecSetOption(in,VEC_IGNORE_OFF_PROC_ENTRIES,PETSC_TRUE);CHKERRQ(ierr); 2740b12b109SJed Brown ierr = VecGetOwnershipRange(out,&start,&end);CHKERRQ(ierr); 2750b12b109SJed Brown ierr = PetscMalloc(m*sizeof(PetscInt),&rows);CHKERRQ(ierr); 276b0a32e0cSBarry Smith for (i=0; i<m; i++) {rows[i] = start + i;} 277b0a32e0cSBarry Smith 278f69a0ea3SMatthew Knepley ierr = MatCreate(comm,mat);CHKERRQ(ierr); 2790b12b109SJed Brown ierr = MatSetSizes(*mat,m,n,M,N);CHKERRQ(ierr); 280b0a32e0cSBarry Smith if (size == 1) { 281be5d1d56SKris Buschelman ierr = MatSetType(*mat,MATSEQDENSE);CHKERRQ(ierr); 282be5d1d56SKris Buschelman ierr = MatSeqDenseSetPreallocation(*mat,PETSC_NULL);CHKERRQ(ierr); 283b0a32e0cSBarry Smith } else { 284be5d1d56SKris Buschelman ierr = MatSetType(*mat,MATMPIAIJ);CHKERRQ(ierr); 2850b12b109SJed Brown ierr = MatMPIAIJSetPreallocation(*mat,n,PETSC_NULL,N-n,PETSC_NULL);CHKERRQ(ierr); 286b0a32e0cSBarry Smith } 287b0a32e0cSBarry Smith 2880b12b109SJed Brown for (i=0; i<N; i++) { 289b0a32e0cSBarry Smith 2902dcb1b2aSMatthew Knepley ierr = VecSet(in,zero);CHKERRQ(ierr); 291b0a32e0cSBarry Smith ierr = VecSetValues(in,1,&i,&one,INSERT_VALUES);CHKERRQ(ierr); 292b0a32e0cSBarry Smith ierr = VecAssemblyBegin(in);CHKERRQ(ierr); 293b0a32e0cSBarry Smith ierr = VecAssemblyEnd(in);CHKERRQ(ierr); 294b0a32e0cSBarry Smith 295b0a32e0cSBarry Smith ierr = MatMult(inmat,in,out);CHKERRQ(ierr); 296b0a32e0cSBarry Smith 297b0a32e0cSBarry Smith ierr = VecGetArray(out,&array);CHKERRQ(ierr); 298b0a32e0cSBarry Smith ierr = MatSetValues(*mat,m,rows,1,&i,array,INSERT_VALUES);CHKERRQ(ierr); 299b0a32e0cSBarry Smith ierr = VecRestoreArray(out,&array);CHKERRQ(ierr); 300b0a32e0cSBarry Smith 301b0a32e0cSBarry Smith } 302b0a32e0cSBarry Smith ierr = PetscFree(rows);CHKERRQ(ierr); 303b0a32e0cSBarry Smith ierr = VecDestroy(out);CHKERRQ(ierr); 304b0a32e0cSBarry Smith ierr = VecDestroy(in);CHKERRQ(ierr); 305b0a32e0cSBarry Smith ierr = MatAssemblyBegin(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 306b0a32e0cSBarry Smith ierr = MatAssemblyEnd(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 307b0a32e0cSBarry Smith PetscFunctionReturn(0); 308b0a32e0cSBarry Smith } 309b0a32e0cSBarry Smith 31024f910e3SHong Zhang /* Get the map xtoy which is used by MatAXPY() in the case of SUBSET_NONZERO_PATTERN */ 31124f910e3SHong Zhang #undef __FUNCT__ 31224f910e3SHong Zhang #define __FUNCT__ "MatAXPYGetxtoy_Private" 31338baddfdSBarry Smith PetscErrorCode MatAXPYGetxtoy_Private(PetscInt m,PetscInt *xi,PetscInt *xj,PetscInt *xgarray, PetscInt *yi,PetscInt *yj,PetscInt *ygarray, PetscInt **xtoy) 31424f910e3SHong Zhang { 3156849ba73SBarry Smith PetscErrorCode ierr; 31638baddfdSBarry Smith PetscInt row,i,nz,xcol,ycol,jx,jy,*x2y; 31724f910e3SHong Zhang 31824f910e3SHong Zhang PetscFunctionBegin; 31938baddfdSBarry Smith ierr = PetscMalloc(xi[m]*sizeof(PetscInt),&x2y);CHKERRQ(ierr); 32024f910e3SHong Zhang i = 0; 32124f910e3SHong Zhang for (row=0; row<m; row++){ 32224f910e3SHong Zhang nz = xi[1] - xi[0]; 32324f910e3SHong Zhang jy = 0; 32424f910e3SHong Zhang for (jx=0; jx<nz; jx++,jy++){ 32524f910e3SHong Zhang if (xgarray && ygarray){ 32624f910e3SHong Zhang xcol = xgarray[xj[*xi + jx]]; 32724f910e3SHong Zhang ycol = ygarray[yj[*yi + jy]]; 32824f910e3SHong Zhang } else { 32924f910e3SHong Zhang xcol = xj[*xi + jx]; 33024f910e3SHong Zhang ycol = yj[*yi + jy]; /* col index for y */ 33124f910e3SHong Zhang } 33224f910e3SHong Zhang while ( ycol < xcol ) { 33324f910e3SHong Zhang jy++; 33424f910e3SHong Zhang if (ygarray){ 33524f910e3SHong Zhang ycol = ygarray[yj[*yi + jy]]; 33624f910e3SHong Zhang } else { 33724f910e3SHong Zhang ycol = yj[*yi + jy]; 33824f910e3SHong Zhang } 33924f910e3SHong Zhang } 34077431f27SBarry Smith if (xcol != ycol) SETERRQ2(PETSC_ERR_ARG_WRONG,"X matrix entry (%D,%D) is not in Y matrix",row,ycol); 34124f910e3SHong Zhang x2y[i++] = *yi + jy; 34224f910e3SHong Zhang } 34324f910e3SHong Zhang xi++; yi++; 34424f910e3SHong Zhang } 34524f910e3SHong Zhang *xtoy = x2y; 34624f910e3SHong Zhang PetscFunctionReturn(0); 34724f910e3SHong Zhang } 348