xref: /petsc/src/mat/utils/axpy.c (revision ce94432eddcd14845bc7e8083b7f8ea723b9bf7d)
16f79c3a4SBarry Smith 
2b45d2f2cSJed Brown #include <petsc-private/matimpl.h>  /*I   "petscmat.h"  I*/
36f79c3a4SBarry Smith 
44a2ae208SSatish Balay #undef __FUNCT__
54a2ae208SSatish Balay #define __FUNCT__ "MatAXPY"
606be10caSBarry Smith /*@
721c89e3eSBarry Smith    MatAXPY - Computes Y = a*X + Y.
86f79c3a4SBarry Smith 
93f9fe445SBarry Smith    Logically  Collective on Mat
10fee21e36SBarry Smith 
1198a79cdbSBarry Smith    Input Parameters:
12607cd303SBarry Smith +  a - the scalar multiplier
13607cd303SBarry Smith .  X - the first matrix
14607cd303SBarry Smith .  Y - the second matrix
15407f6b05SHong Zhang -  str - either SAME_NONZERO_PATTERN, DIFFERENT_NONZERO_PATTERN
16407f6b05SHong Zhang          or SUBSET_NONZERO_PATTERN (nonzeros of X is a subset of Y's)
1798a79cdbSBarry Smith 
182860a424SLois Curfman McInnes    Level: intermediate
192860a424SLois Curfman McInnes 
209cf4f1e8SLois Curfman McInnes .keywords: matrix, add
21d4bb536fSBarry Smith 
222860a424SLois Curfman McInnes .seealso: MatAYPX()
2306be10caSBarry Smith  @*/
247087cfbeSBarry Smith PetscErrorCode  MatAXPY(Mat Y,PetscScalar a,Mat X,MatStructure str)
256f79c3a4SBarry Smith {
266849ba73SBarry Smith   PetscErrorCode ierr;
27c1ac3661SBarry Smith   PetscInt       m1,m2,n1,n2;
286f79c3a4SBarry Smith 
293a40ed3dSBarry Smith   PetscFunctionBegin;
300700a824SBarry Smith   PetscValidHeaderSpecific(X,MAT_CLASSID,3);
310700a824SBarry Smith   PetscValidHeaderSpecific(Y,MAT_CLASSID,1);
32c5eb9154SBarry Smith   PetscValidLogicalCollectiveScalar(Y,a,2);
33273d9f13SBarry Smith   ierr = MatGetSize(X,&m1,&n1);CHKERRQ(ierr);
34273d9f13SBarry Smith   ierr = MatGetSize(Y,&m2,&n2);CHKERRQ(ierr);
35e32f2f54SBarry Smith   if (m1 != m2 || n1 != n2) SETERRQ4(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Non conforming matrix add: %D %D %D %D",m1,m2,n1,n2);
361987afe7SBarry Smith 
37e8136da8SHong Zhang   ierr = PetscLogEventBegin(MAT_AXPY,Y,0,0,0);CHKERRQ(ierr);
38f4df32b1SMatthew Knepley   if (Y->ops->axpy) {
39f4df32b1SMatthew Knepley     ierr = (*Y->ops->axpy)(Y,a,X,str);CHKERRQ(ierr);
40d4bb536fSBarry Smith   } else {
41f4df32b1SMatthew Knepley     ierr = MatAXPY_Basic(Y,a,X,str);CHKERRQ(ierr);
42607cd303SBarry Smith   }
43e8136da8SHong Zhang   ierr = PetscLogEventEnd(MAT_AXPY,Y,0,0,0);CHKERRQ(ierr);
442eea6e16SBarry Smith #if defined(PETSC_HAVE_CUSP)
452eea6e16SBarry Smith   if (Y->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
462eea6e16SBarry Smith     Y->valid_GPU_matrix = PETSC_CUSP_CPU;
472eea6e16SBarry Smith   }
482eea6e16SBarry Smith #endif
49607cd303SBarry Smith   PetscFunctionReturn(0);
50607cd303SBarry Smith }
51607cd303SBarry Smith 
52607cd303SBarry Smith #undef __FUNCT__
53607cd303SBarry Smith #define __FUNCT__ "MatAXPY_Basic"
54f4df32b1SMatthew Knepley PetscErrorCode MatAXPY_Basic(Mat Y,PetscScalar a,Mat X,MatStructure str)
55607cd303SBarry Smith {
5638baddfdSBarry Smith   PetscInt          i,start,end,j,ncols,m,n;
576849ba73SBarry Smith   PetscErrorCode    ierr;
5838baddfdSBarry Smith   const PetscInt    *row;
59b3cc6726SBarry Smith   PetscScalar       *val;
60b3cc6726SBarry Smith   const PetscScalar *vals;
61607cd303SBarry Smith 
62607cd303SBarry Smith   PetscFunctionBegin;
638dadbd76SSatish Balay   ierr = MatGetSize(X,&m,&n);CHKERRQ(ierr);
6490f02eecSBarry Smith   ierr = MatGetOwnershipRange(X,&start,&end);CHKERRQ(ierr);
65f4df32b1SMatthew Knepley   if (a == 1.0) {
66d4bb536fSBarry Smith     for (i = start; i < end; i++) {
67d4bb536fSBarry Smith       ierr = MatGetRow(X,i,&ncols,&row,&vals);CHKERRQ(ierr);
68d4bb536fSBarry Smith       ierr = MatSetValues(Y,1,&i,ncols,row,vals,ADD_VALUES);CHKERRQ(ierr);
69d4bb536fSBarry Smith       ierr = MatRestoreRow(X,i,&ncols,&row,&vals);CHKERRQ(ierr);
70d4bb536fSBarry Smith     }
71d4bb536fSBarry Smith   } else {
72b3cc6726SBarry Smith     ierr = PetscMalloc((n+1)*sizeof(PetscScalar),&val);CHKERRQ(ierr);
7306be10caSBarry Smith     for (i=start; i<end; i++) {
74b3cc6726SBarry Smith       ierr = MatGetRow(X,i,&ncols,&row,&vals);CHKERRQ(ierr);
7506be10caSBarry Smith       for (j=0; j<ncols; j++) {
76f4df32b1SMatthew Knepley         val[j] = a*vals[j];
776f79c3a4SBarry Smith       }
78b3cc6726SBarry Smith       ierr = MatSetValues(Y,1,&i,ncols,row,val,ADD_VALUES);CHKERRQ(ierr);
79b3cc6726SBarry Smith       ierr = MatRestoreRow(X,i,&ncols,&row,&vals);CHKERRQ(ierr);
806f79c3a4SBarry Smith     }
81b3cc6726SBarry Smith     ierr = PetscFree(val);CHKERRQ(ierr);
82d4bb536fSBarry Smith   }
836d4a8577SBarry Smith   ierr = MatAssemblyBegin(Y,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
846d4a8577SBarry Smith   ierr = MatAssemblyEnd(Y,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
853a40ed3dSBarry Smith   PetscFunctionReturn(0);
866f79c3a4SBarry Smith }
87052efed2SBarry Smith 
884a2ae208SSatish Balay #undef __FUNCT__
89ec7775f6SShri Abhyankar #define __FUNCT__ "MatAXPY_BasicWithPreallocation"
90ec7775f6SShri Abhyankar PetscErrorCode MatAXPY_BasicWithPreallocation(Mat B,Mat Y,PetscScalar a,Mat X,MatStructure str)
91ec7775f6SShri Abhyankar {
92ec7775f6SShri Abhyankar   PetscInt          i,start,end,j,ncols,m,n;
93ec7775f6SShri Abhyankar   PetscErrorCode    ierr;
94ec7775f6SShri Abhyankar   const PetscInt    *row;
95ec7775f6SShri Abhyankar   PetscScalar       *val;
96ec7775f6SShri Abhyankar   const PetscScalar *vals;
97ec7775f6SShri Abhyankar 
98ec7775f6SShri Abhyankar   PetscFunctionBegin;
99ec7775f6SShri Abhyankar   ierr = MatGetSize(X,&m,&n);CHKERRQ(ierr);
100ec7775f6SShri Abhyankar   ierr = MatGetOwnershipRange(X,&start,&end);CHKERRQ(ierr);
101ec7775f6SShri Abhyankar   if (a == 1.0) {
102ec7775f6SShri Abhyankar     for (i = start; i < end; i++) {
103ec7775f6SShri Abhyankar       ierr = MatGetRow(Y,i,&ncols,&row,&vals);CHKERRQ(ierr);
104ec7775f6SShri Abhyankar       ierr = MatSetValues(B,1,&i,ncols,row,vals,ADD_VALUES);CHKERRQ(ierr);
105ec7775f6SShri Abhyankar       ierr = MatRestoreRow(Y,i,&ncols,&row,&vals);CHKERRQ(ierr);
106ec7775f6SShri Abhyankar 
107ec7775f6SShri Abhyankar       ierr = MatGetRow(X,i,&ncols,&row,&vals);CHKERRQ(ierr);
108ec7775f6SShri Abhyankar       ierr = MatSetValues(B,1,&i,ncols,row,vals,ADD_VALUES);CHKERRQ(ierr);
109ec7775f6SShri Abhyankar       ierr = MatRestoreRow(X,i,&ncols,&row,&vals);CHKERRQ(ierr);
110ec7775f6SShri Abhyankar     }
111ec7775f6SShri Abhyankar   } else {
112ec7775f6SShri Abhyankar     ierr = PetscMalloc((n+1)*sizeof(PetscScalar),&val);CHKERRQ(ierr);
113ec7775f6SShri Abhyankar     for (i=start; i<end; i++) {
114ec7775f6SShri Abhyankar       ierr = MatGetRow(Y,i,&ncols,&row,&vals);CHKERRQ(ierr);
115ec7775f6SShri Abhyankar       ierr = MatSetValues(B,1,&i,ncols,row,vals,ADD_VALUES);CHKERRQ(ierr);
116ec7775f6SShri Abhyankar       ierr = MatRestoreRow(Y,i,&ncols,&row,&vals);CHKERRQ(ierr);
117ec7775f6SShri Abhyankar 
118ec7775f6SShri Abhyankar       ierr = MatGetRow(X,i,&ncols,&row,&vals);CHKERRQ(ierr);
119ec7775f6SShri Abhyankar       for (j=0; j<ncols; j++) {
120ec7775f6SShri Abhyankar         val[j] = a*vals[j];
121ec7775f6SShri Abhyankar       }
122ec7775f6SShri Abhyankar       ierr = MatSetValues(B,1,&i,ncols,row,val,ADD_VALUES);CHKERRQ(ierr);
123ec7775f6SShri Abhyankar       ierr = MatRestoreRow(X,i,&ncols,&row,&vals);CHKERRQ(ierr);
124ec7775f6SShri Abhyankar     }
125ec7775f6SShri Abhyankar     ierr = PetscFree(val);CHKERRQ(ierr);
126ec7775f6SShri Abhyankar   }
127ec7775f6SShri Abhyankar   ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
128ec7775f6SShri Abhyankar   ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
129ec7775f6SShri Abhyankar   PetscFunctionReturn(0);
130ec7775f6SShri Abhyankar }
131ec7775f6SShri Abhyankar 
132ec7775f6SShri Abhyankar #undef __FUNCT__
1334a2ae208SSatish Balay #define __FUNCT__ "MatShift"
134052efed2SBarry Smith /*@
13587828ca2SBarry Smith    MatShift - Computes Y =  Y + a I, where a is a PetscScalar and I is the identity matrix.
136052efed2SBarry Smith 
1373f9fe445SBarry Smith    Neighbor-wise Collective on Mat
138fee21e36SBarry Smith 
13998a79cdbSBarry Smith    Input Parameters:
14098a79cdbSBarry Smith +  Y - the matrices
14187828ca2SBarry Smith -  a - the PetscScalar
14298a79cdbSBarry Smith 
1432860a424SLois Curfman McInnes    Level: intermediate
1442860a424SLois Curfman McInnes 
145052efed2SBarry Smith .keywords: matrix, add, shift
1466b9ee512SLois Curfman McInnes 
147f56f2b3fSBarry Smith .seealso: MatDiagonalSet()
148052efed2SBarry Smith  @*/
1497087cfbeSBarry Smith PetscErrorCode  MatShift(Mat Y,PetscScalar a)
150052efed2SBarry Smith {
1516849ba73SBarry Smith   PetscErrorCode ierr;
15238baddfdSBarry Smith   PetscInt       i,start,end;
153052efed2SBarry Smith 
1543a40ed3dSBarry Smith   PetscFunctionBegin;
1550700a824SBarry Smith   PetscValidHeaderSpecific(Y,MAT_CLASSID,1);
156*ce94432eSBarry Smith   if (!Y->assembled) SETERRQ(PetscObjectComm((PetscObject)Y),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
157*ce94432eSBarry Smith   if (Y->factortype) SETERRQ(PetscObjectComm((PetscObject)Y),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1584994cf47SJed Brown   MatCheckPreallocated(Y,1);
159b50b34bdSBarry Smith 
160f830108cSBarry Smith   if (Y->ops->shift) {
161f4df32b1SMatthew Knepley     ierr = (*Y->ops->shift)(Y,a);CHKERRQ(ierr);
16262d58ce1SBarry Smith   } else {
163f4df32b1SMatthew Knepley     PetscScalar alpha = a;
164d4bb536fSBarry Smith     ierr = MatGetOwnershipRange(Y,&start,&end);CHKERRQ(ierr);
165052efed2SBarry Smith     for (i=start; i<end; i++) {
166f4df32b1SMatthew Knepley       ierr = MatSetValues(Y,1,&i,1,&i,&alpha,ADD_VALUES);CHKERRQ(ierr);
167052efed2SBarry Smith     }
1686d4a8577SBarry Smith     ierr = MatAssemblyBegin(Y,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
1696d4a8577SBarry Smith     ierr = MatAssemblyEnd(Y,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
170052efed2SBarry Smith   }
1712eea6e16SBarry Smith #if defined(PETSC_HAVE_CUSP)
1722eea6e16SBarry Smith   if (Y->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
1732eea6e16SBarry Smith     Y->valid_GPU_matrix = PETSC_CUSP_CPU;
1742eea6e16SBarry Smith   }
1752eea6e16SBarry Smith #endif
1763a40ed3dSBarry Smith   PetscFunctionReturn(0);
177052efed2SBarry Smith }
1786d84be18SBarry Smith 
1794a2ae208SSatish Balay #undef __FUNCT__
18009f38230SBarry Smith #define __FUNCT__ "MatDiagonalSet_Default"
1817087cfbeSBarry Smith PetscErrorCode  MatDiagonalSet_Default(Mat Y,Vec D,InsertMode is)
18209f38230SBarry Smith {
18309f38230SBarry Smith   PetscErrorCode ierr;
18409f38230SBarry Smith   PetscInt       i,start,end,vstart,vend;
18509f38230SBarry Smith   PetscScalar    *v;
18609f38230SBarry Smith 
18709f38230SBarry Smith   PetscFunctionBegin;
18809f38230SBarry Smith   ierr = VecGetOwnershipRange(D,&vstart,&vend);CHKERRQ(ierr);
18909f38230SBarry Smith   ierr = MatGetOwnershipRange(Y,&start,&end);CHKERRQ(ierr);
190ae9be289SBarry Smith   if (vstart != start || vend != end) SETERRQ4(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Vector ownership range not compatible with matrix: %D %D vec %D %D mat",vstart,vend,start,end);
19109f38230SBarry Smith   ierr = VecGetArray(D,&v);CHKERRQ(ierr);
19209f38230SBarry Smith   for (i=start; i<end; i++) {
19309f38230SBarry Smith     ierr = MatSetValues(Y,1,&i,1,&i,v+i-start,is);CHKERRQ(ierr);
19409f38230SBarry Smith   }
19509f38230SBarry Smith   ierr = VecRestoreArray(D,&v);CHKERRQ(ierr);
19609f38230SBarry Smith   ierr = MatAssemblyBegin(Y,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
19709f38230SBarry Smith   ierr = MatAssemblyEnd(Y,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
19809f38230SBarry Smith   PetscFunctionReturn(0);
19909f38230SBarry Smith }
20009f38230SBarry Smith 
20109f38230SBarry Smith #undef __FUNCT__
2024a2ae208SSatish Balay #define __FUNCT__ "MatDiagonalSet"
2036d84be18SBarry Smith /*@
204f56f2b3fSBarry Smith    MatDiagonalSet - Computes Y = Y + D, where D is a diagonal matrix
205f56f2b3fSBarry Smith    that is represented as a vector. Or Y[i,i] = D[i] if InsertMode is
206f56f2b3fSBarry Smith    INSERT_VALUES.
2076d84be18SBarry Smith 
2086d84be18SBarry Smith    Input Parameters:
20998a79cdbSBarry Smith +  Y - the input matrix
210f56f2b3fSBarry Smith .  D - the diagonal matrix, represented as a vector
211f56f2b3fSBarry Smith -  i - INSERT_VALUES or ADD_VALUES
2126d84be18SBarry Smith 
2133f9fe445SBarry Smith    Neighbor-wise Collective on Mat and Vec
214fee21e36SBarry Smith 
2152860a424SLois Curfman McInnes    Level: intermediate
2162860a424SLois Curfman McInnes 
2176b9ee512SLois Curfman McInnes .keywords: matrix, add, shift, diagonal
2186b9ee512SLois Curfman McInnes 
2196b9ee512SLois Curfman McInnes .seealso: MatShift()
2206d84be18SBarry Smith @*/
2217087cfbeSBarry Smith PetscErrorCode  MatDiagonalSet(Mat Y,Vec D,InsertMode is)
2226d84be18SBarry Smith {
2236849ba73SBarry Smith   PetscErrorCode ierr;
2246d84be18SBarry Smith 
2253a40ed3dSBarry Smith   PetscFunctionBegin;
2260700a824SBarry Smith   PetscValidHeaderSpecific(Y,MAT_CLASSID,1);
2270700a824SBarry Smith   PetscValidHeaderSpecific(D,VEC_CLASSID,2);
228f56f2b3fSBarry Smith   if (Y->ops->diagonalset) {
229f56f2b3fSBarry Smith     ierr = (*Y->ops->diagonalset)(Y,D,is);CHKERRQ(ierr);
23094d884c6SBarry Smith   } else {
23109f38230SBarry Smith     ierr = MatDiagonalSet_Default(Y,D,is);CHKERRQ(ierr);
2326d84be18SBarry Smith   }
2333a40ed3dSBarry Smith   PetscFunctionReturn(0);
2346d84be18SBarry Smith }
235d4bb536fSBarry Smith 
2364a2ae208SSatish Balay #undef __FUNCT__
2374a2ae208SSatish Balay #define __FUNCT__ "MatAYPX"
238d4bb536fSBarry Smith /*@
23904aac2b0SHong Zhang    MatAYPX - Computes Y = a*Y + X.
240d4bb536fSBarry Smith 
2413f9fe445SBarry Smith    Logically on Mat
242fee21e36SBarry Smith 
24398a79cdbSBarry Smith    Input Parameters:
24404aac2b0SHong Zhang +  a - the PetscScalar multiplier
24504aac2b0SHong Zhang .  Y - the first matrix
24604aac2b0SHong Zhang .  X - the second matrix
24704aac2b0SHong Zhang -  str - either SAME_NONZERO_PATTERN, DIFFERENT_NONZERO_PATTERN or SUBSET_NONZERO_PATTERN
248d4bb536fSBarry Smith 
2492860a424SLois Curfman McInnes    Level: intermediate
2502860a424SLois Curfman McInnes 
251d4bb536fSBarry Smith .keywords: matrix, add
252d4bb536fSBarry Smith 
2532860a424SLois Curfman McInnes .seealso: MatAXPY()
254d4bb536fSBarry Smith  @*/
2557087cfbeSBarry Smith PetscErrorCode  MatAYPX(Mat Y,PetscScalar a,Mat X,MatStructure str)
256d4bb536fSBarry Smith {
25787828ca2SBarry Smith   PetscScalar    one = 1.0;
2586849ba73SBarry Smith   PetscErrorCode ierr;
25938baddfdSBarry Smith   PetscInt       mX,mY,nX,nY;
260d4bb536fSBarry Smith 
2613a40ed3dSBarry Smith   PetscFunctionBegin;
262c5eb9154SBarry Smith   PetscValidHeaderSpecific(X,MAT_CLASSID,3);
2630700a824SBarry Smith   PetscValidHeaderSpecific(Y,MAT_CLASSID,1);
264c5eb9154SBarry Smith   PetscValidLogicalCollectiveScalar(Y,a,2);
265329f5518SBarry Smith   ierr = MatGetSize(X,&mX,&nX);CHKERRQ(ierr);
266329f5518SBarry Smith   ierr = MatGetSize(X,&mY,&nY);CHKERRQ(ierr);
267e32f2f54SBarry Smith   if (mX != mY || nX != nY) SETERRQ4(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Non conforming matrices: %D %D first %D %D second",mX,mY,nX,nY);
268d4bb536fSBarry Smith 
269f4df32b1SMatthew Knepley   ierr = MatScale(Y,a);CHKERRQ(ierr);
270cb9801acSJed Brown   ierr = MatAXPY(Y,one,X,str);CHKERRQ(ierr);
2713a40ed3dSBarry Smith   PetscFunctionReturn(0);
272d4bb536fSBarry Smith }
273b0a32e0cSBarry Smith 
2744a2ae208SSatish Balay #undef __FUNCT__
2754a2ae208SSatish Balay #define __FUNCT__ "MatComputeExplicitOperator"
276b0a32e0cSBarry Smith /*@
277b0a32e0cSBarry Smith     MatComputeExplicitOperator - Computes the explicit matrix
278b0a32e0cSBarry Smith 
279b0a32e0cSBarry Smith     Collective on Mat
280b0a32e0cSBarry Smith 
281b0a32e0cSBarry Smith     Input Parameter:
282b0a32e0cSBarry Smith .   inmat - the matrix
283b0a32e0cSBarry Smith 
284b0a32e0cSBarry Smith     Output Parameter:
285b0a32e0cSBarry Smith .   mat - the explict preconditioned operator
286b0a32e0cSBarry Smith 
287b0a32e0cSBarry Smith     Notes:
288b0a32e0cSBarry Smith     This computation is done by applying the operators to columns of the
289b0a32e0cSBarry Smith     identity matrix.
290b0a32e0cSBarry Smith 
291b0a32e0cSBarry Smith     Currently, this routine uses a dense matrix format when 1 processor
292b0a32e0cSBarry Smith     is used and a sparse format otherwise.  This routine is costly in general,
293b0a32e0cSBarry Smith     and is recommended for use only with relatively small systems.
294b0a32e0cSBarry Smith 
295b0a32e0cSBarry Smith     Level: advanced
296b0a32e0cSBarry Smith 
297b0a32e0cSBarry Smith .keywords: Mat, compute, explicit, operator
298b0a32e0cSBarry Smith @*/
2997087cfbeSBarry Smith PetscErrorCode  MatComputeExplicitOperator(Mat inmat,Mat *mat)
300b0a32e0cSBarry Smith {
301b0a32e0cSBarry Smith   Vec            in,out;
302dfbe8321SBarry Smith   PetscErrorCode ierr;
3030b12b109SJed Brown   PetscInt       i,m,n,M,N,*rows,start,end;
304b0a32e0cSBarry Smith   MPI_Comm       comm;
30587828ca2SBarry Smith   PetscScalar    *array,zero = 0.0,one = 1.0;
30638baddfdSBarry Smith   PetscMPIInt    size;
307b0a32e0cSBarry Smith 
308b0a32e0cSBarry Smith   PetscFunctionBegin;
3090700a824SBarry Smith   PetscValidHeaderSpecific(inmat,MAT_CLASSID,1);
3104482741eSBarry Smith   PetscValidPointer(mat,2);
311b0a32e0cSBarry Smith 
312*ce94432eSBarry Smith   ierr = PetscObjectGetComm((PetscObject)inmat,&comm);CHKERRQ(ierr);
313b0a32e0cSBarry Smith   ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
314b0a32e0cSBarry Smith 
3150b12b109SJed Brown   ierr = MatGetLocalSize(inmat,&m,&n);CHKERRQ(ierr);
3160b12b109SJed Brown   ierr = MatGetSize(inmat,&M,&N);CHKERRQ(ierr);
3170b12b109SJed Brown   ierr = MatGetVecs(inmat,&in,&out);CHKERRQ(ierr);
3180b12b109SJed Brown   ierr = VecSetOption(in,VEC_IGNORE_OFF_PROC_ENTRIES,PETSC_TRUE);CHKERRQ(ierr);
3190b12b109SJed Brown   ierr = VecGetOwnershipRange(out,&start,&end);CHKERRQ(ierr);
3200b12b109SJed Brown   ierr = PetscMalloc(m*sizeof(PetscInt),&rows);CHKERRQ(ierr);
3218865f1eaSKarl Rupp   for (i=0; i<m; i++) rows[i] = start + i;
322b0a32e0cSBarry Smith 
323f69a0ea3SMatthew Knepley   ierr = MatCreate(comm,mat);CHKERRQ(ierr);
3240b12b109SJed Brown   ierr = MatSetSizes(*mat,m,n,M,N);CHKERRQ(ierr);
325b0a32e0cSBarry Smith   if (size == 1) {
326be5d1d56SKris Buschelman     ierr = MatSetType(*mat,MATSEQDENSE);CHKERRQ(ierr);
3270298fd71SBarry Smith     ierr = MatSeqDenseSetPreallocation(*mat,NULL);CHKERRQ(ierr);
328b0a32e0cSBarry Smith   } else {
329be5d1d56SKris Buschelman     ierr = MatSetType(*mat,MATMPIAIJ);CHKERRQ(ierr);
3300298fd71SBarry Smith     ierr = MatMPIAIJSetPreallocation(*mat,n,NULL,N-n,NULL);CHKERRQ(ierr);
331b0a32e0cSBarry Smith   }
332b0a32e0cSBarry Smith 
3330b12b109SJed Brown   for (i=0; i<N; i++) {
334b0a32e0cSBarry Smith 
3352dcb1b2aSMatthew Knepley     ierr = VecSet(in,zero);CHKERRQ(ierr);
336b0a32e0cSBarry Smith     ierr = VecSetValues(in,1,&i,&one,INSERT_VALUES);CHKERRQ(ierr);
337b0a32e0cSBarry Smith     ierr = VecAssemblyBegin(in);CHKERRQ(ierr);
338b0a32e0cSBarry Smith     ierr = VecAssemblyEnd(in);CHKERRQ(ierr);
339b0a32e0cSBarry Smith 
340b0a32e0cSBarry Smith     ierr = MatMult(inmat,in,out);CHKERRQ(ierr);
341b0a32e0cSBarry Smith 
342b0a32e0cSBarry Smith     ierr = VecGetArray(out,&array);CHKERRQ(ierr);
343b0a32e0cSBarry Smith     ierr = MatSetValues(*mat,m,rows,1,&i,array,INSERT_VALUES);CHKERRQ(ierr);
344b0a32e0cSBarry Smith     ierr = VecRestoreArray(out,&array);CHKERRQ(ierr);
345b0a32e0cSBarry Smith 
346b0a32e0cSBarry Smith   }
347b0a32e0cSBarry Smith   ierr = PetscFree(rows);CHKERRQ(ierr);
3486bf464f9SBarry Smith   ierr = VecDestroy(&out);CHKERRQ(ierr);
3496bf464f9SBarry Smith   ierr = VecDestroy(&in);CHKERRQ(ierr);
350b0a32e0cSBarry Smith   ierr = MatAssemblyBegin(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
351b0a32e0cSBarry Smith   ierr = MatAssemblyEnd(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
352b0a32e0cSBarry Smith   PetscFunctionReturn(0);
353b0a32e0cSBarry Smith }
354b0a32e0cSBarry Smith 
35524f910e3SHong Zhang /* Get the map xtoy which is used by MatAXPY() in the case of SUBSET_NONZERO_PATTERN */
35624f910e3SHong Zhang #undef __FUNCT__
35724f910e3SHong Zhang #define __FUNCT__ "MatAXPYGetxtoy_Private"
35838baddfdSBarry Smith PetscErrorCode MatAXPYGetxtoy_Private(PetscInt m,PetscInt *xi,PetscInt *xj,PetscInt *xgarray, PetscInt *yi,PetscInt *yj,PetscInt *ygarray, PetscInt **xtoy)
35924f910e3SHong Zhang {
3606849ba73SBarry Smith   PetscErrorCode ierr;
36138baddfdSBarry Smith   PetscInt       row,i,nz,xcol,ycol,jx,jy,*x2y;
36224f910e3SHong Zhang 
36324f910e3SHong Zhang   PetscFunctionBegin;
36438baddfdSBarry Smith   ierr = PetscMalloc(xi[m]*sizeof(PetscInt),&x2y);CHKERRQ(ierr);
36524f910e3SHong Zhang   i    = 0;
36624f910e3SHong Zhang   for (row=0; row<m; row++) {
36724f910e3SHong Zhang     nz = xi[1] - xi[0];
36824f910e3SHong Zhang     jy = 0;
36924f910e3SHong Zhang     for (jx=0; jx<nz; jx++,jy++) {
37024f910e3SHong Zhang       if (xgarray && ygarray) {
37124f910e3SHong Zhang         xcol = xgarray[xj[*xi + jx]];
37224f910e3SHong Zhang         ycol = ygarray[yj[*yi + jy]];
37324f910e3SHong Zhang       } else {
37424f910e3SHong Zhang         xcol = xj[*xi + jx];
37524f910e3SHong Zhang         ycol = yj[*yi + jy];  /* col index for y */
37624f910e3SHong Zhang       }
37724f910e3SHong Zhang       while (ycol < xcol) {
37824f910e3SHong Zhang         jy++;
37924f910e3SHong Zhang         if (ygarray) {
38024f910e3SHong Zhang           ycol = ygarray[yj[*yi + jy]];
38124f910e3SHong Zhang         } else {
38224f910e3SHong Zhang           ycol = yj[*yi + jy];
38324f910e3SHong Zhang         }
38424f910e3SHong Zhang       }
385e32f2f54SBarry Smith       if (xcol != ycol) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"X matrix entry (%D,%D) is not in Y matrix",row,ycol);
38624f910e3SHong Zhang       x2y[i++] = *yi + jy;
38724f910e3SHong Zhang     }
38824f910e3SHong Zhang     xi++; yi++;
38924f910e3SHong Zhang   }
39024f910e3SHong Zhang   *xtoy = x2y;
39124f910e3SHong Zhang   PetscFunctionReturn(0);
39224f910e3SHong Zhang }
3934325cce7SMatthew G Knepley 
3944325cce7SMatthew G Knepley #undef __FUNCT__
3954325cce7SMatthew G Knepley #define __FUNCT__ "MatChop"
3964325cce7SMatthew G Knepley /*@
3974325cce7SMatthew G Knepley   MatChop - Set all values in the matrix less than the tolerance to zero
3984325cce7SMatthew G Knepley 
3994325cce7SMatthew G Knepley   Input Parameters:
4004325cce7SMatthew G Knepley + A   - The matrix
4014325cce7SMatthew G Knepley - tol - The zero tolerance
4024325cce7SMatthew G Knepley 
4034325cce7SMatthew G Knepley   Output Parameters:
4044325cce7SMatthew G Knepley . A - The chopped matrix
4054325cce7SMatthew G Knepley 
4064325cce7SMatthew G Knepley   Level: intermediate
4074325cce7SMatthew G Knepley 
4084325cce7SMatthew G Knepley .seealso: MatCreate(), MatZeroEntries()
4093fc99919SSatish Balay  @*/
4104325cce7SMatthew G Knepley PetscErrorCode MatChop(Mat A, PetscReal tol)
4114325cce7SMatthew G Knepley {
4124325cce7SMatthew G Knepley   PetscScalar    *newVals;
4134325cce7SMatthew G Knepley   PetscInt       *newCols;
4144325cce7SMatthew G Knepley   PetscInt       rStart, rEnd, numRows, maxRows, r, colMax = 0;
4154325cce7SMatthew G Knepley   PetscErrorCode ierr;
4164325cce7SMatthew G Knepley 
4174325cce7SMatthew G Knepley   PetscFunctionBegin;
4184325cce7SMatthew G Knepley   ierr = MatGetOwnershipRange(A, &rStart, &rEnd);CHKERRQ(ierr);
4194325cce7SMatthew G Knepley   for (r = rStart; r < rEnd; ++r) {
4204325cce7SMatthew G Knepley     PetscInt ncols;
4214325cce7SMatthew G Knepley 
4220298fd71SBarry Smith     ierr   = MatGetRow(A, r, &ncols, NULL, NULL);CHKERRQ(ierr);
4234325cce7SMatthew G Knepley     colMax = PetscMax(colMax, ncols);CHKERRQ(ierr);
4240298fd71SBarry Smith     ierr   = MatRestoreRow(A, r, &ncols, NULL, NULL);CHKERRQ(ierr);
4254325cce7SMatthew G Knepley   }
4264325cce7SMatthew G Knepley   numRows = rEnd - rStart;
4274325cce7SMatthew G Knepley   ierr    = MPI_Allreduce(&numRows, &maxRows, 1, MPIU_INT, MPI_MAX, PETSC_COMM_WORLD);CHKERRQ(ierr);
4284325cce7SMatthew G Knepley   ierr    = PetscMalloc2(colMax,PetscInt,&newCols,colMax,PetscScalar,&newVals);CHKERRQ(ierr);
4294325cce7SMatthew G Knepley   for (r = rStart; r < rStart+maxRows; ++r) {
4304325cce7SMatthew G Knepley     const PetscScalar *vals;
4314325cce7SMatthew G Knepley     const PetscInt    *cols;
4324325cce7SMatthew G Knepley     PetscInt          ncols, c;
4334325cce7SMatthew G Knepley 
4344325cce7SMatthew G Knepley     if (r < rEnd) {
4354325cce7SMatthew G Knepley       ierr = MatGetRow(A, r, &ncols, &cols, &vals);CHKERRQ(ierr);
4364325cce7SMatthew G Knepley       for (c = 0; c < ncols; ++c) {
4374325cce7SMatthew G Knepley         newCols[c] = cols[c];
4384325cce7SMatthew G Knepley         newVals[c] = PetscAbsScalar(vals[c]) < tol ? 0.0 : vals[c];
4394325cce7SMatthew G Knepley       }
4404325cce7SMatthew G Knepley       ierr = MatRestoreRow(A, r, &ncols, &cols, &vals);CHKERRQ(ierr);
4414325cce7SMatthew G Knepley       ierr = MatSetValues(A, 1, &r, ncols, newCols, newVals, INSERT_VALUES);CHKERRQ(ierr);
4424325cce7SMatthew G Knepley     }
4434325cce7SMatthew G Knepley     ierr = MatAssemblyBegin(A, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
4444325cce7SMatthew G Knepley     ierr = MatAssemblyEnd(A, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
4454325cce7SMatthew G Knepley   }
4464325cce7SMatthew G Knepley   ierr = PetscFree2(newCols,newVals);CHKERRQ(ierr);
4474325cce7SMatthew G Knepley   PetscFunctionReturn(0);
4484325cce7SMatthew G Knepley }
449