xref: /petsc/src/mat/utils/axpy.c (revision 607cd303d4877cc3e3442d2c38e0ac4da6c61802)
1bba1ac68SSatish Balay /*$Id: axpy.c,v 1.54 2001/08/06 21:16:10 bsmith Exp bsmith $*/
26f79c3a4SBarry Smith 
3e090d566SSatish Balay #include "src/mat/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:
13*607cd303SBarry Smith +  a - the scalar multiplier
14*607cd303SBarry Smith .  X - the first matrix
15*607cd303SBarry Smith .  Y - the second matrix
16*607cd303SBarry Smith -  str - either SAME_NONZERO_PATTERN or DIFFERENT_NONZERO_PATTERN
1798a79cdbSBarry Smith 
18e182c471SBarry Smith    Contributed by: Matthew Knepley
19d4bb536fSBarry Smith 
202860a424SLois Curfman McInnes    Notes:
21*607cd303SBarry Smith      Will only be efficient if one has the SAME_NONZERO_PATTERN
222860a424SLois Curfman McInnes 
232860a424SLois Curfman McInnes    Level: intermediate
242860a424SLois Curfman McInnes 
259cf4f1e8SLois Curfman McInnes .keywords: matrix, add
26d4bb536fSBarry Smith 
272860a424SLois Curfman McInnes .seealso: MatAYPX()
2806be10caSBarry Smith  @*/
29*607cd303SBarry Smith int MatAXPY(PetscScalar *a,Mat X,Mat Y,MatStructure str)
306f79c3a4SBarry Smith {
3106be10caSBarry Smith   int         m1,m2,n1,n2,i,*row,start,end,j,ncols,ierr;
3287828ca2SBarry Smith   PetscScalar *val,*vals;
336f79c3a4SBarry Smith 
343a40ed3dSBarry Smith   PetscFunctionBegin;
35d4bb536fSBarry Smith   PetscValidHeaderSpecific(X,MAT_COOKIE);
36d4bb536fSBarry Smith   PetscValidHeaderSpecific(Y,MAT_COOKIE);
3790f02eecSBarry Smith   PetscValidScalarPointer(a);
3890f02eecSBarry Smith 
39273d9f13SBarry Smith   ierr = MatGetSize(X,&m1,&n1);CHKERRQ(ierr);
40273d9f13SBarry Smith   ierr = MatGetSize(Y,&m2,&n2);CHKERRQ(ierr);
4129bbc08cSBarry Smith   if (m1 != m2 || n1 != n2) SETERRQ4(PETSC_ERR_ARG_SIZ,"Non conforming matrix add: %d %d %d %d",m1,m2,n1,n2);
421987afe7SBarry Smith 
43f830108cSBarry Smith   if (X->ops->axpy) {
44*607cd303SBarry Smith     ierr = (*X->ops->axpy)(a,X,Y,str);CHKERRQ(ierr);
45d4bb536fSBarry Smith   } else {
46*607cd303SBarry Smith     ierr = MatAXPY_Basic(a,X,Y,str);CHKERRQ(ierr);
47*607cd303SBarry Smith   }
48*607cd303SBarry Smith   PetscFunctionReturn(0);
49*607cd303SBarry Smith }
50*607cd303SBarry Smith 
51*607cd303SBarry Smith 
52*607cd303SBarry Smith #undef __FUNCT__
53*607cd303SBarry Smith #define __FUNCT__ "MatAXPY_Basic"
54*607cd303SBarry Smith int MatAXPY_Basic(PetscScalar *a,Mat X,Mat Y,MatStructure str)
55*607cd303SBarry Smith {
56*607cd303SBarry Smith   int         i,*row,start,end,j,ncols,ierr;
57*607cd303SBarry Smith   PetscScalar *val,*vals;
58*607cd303SBarry Smith 
59*607cd303SBarry Smith   PetscFunctionBegin;
6090f02eecSBarry Smith   ierr = MatGetOwnershipRange(X,&start,&end);CHKERRQ(ierr);
61d4bb536fSBarry Smith   if (*a == 1.0) {
62d4bb536fSBarry Smith     for (i = start; i < end; i++) {
63d4bb536fSBarry Smith       ierr = MatGetRow(X,i,&ncols,&row,&vals);CHKERRQ(ierr);
64d4bb536fSBarry Smith       ierr = MatSetValues(Y,1,&i,ncols,row,vals,ADD_VALUES);CHKERRQ(ierr);
65d4bb536fSBarry Smith       ierr = MatRestoreRow(X,i,&ncols,&row,&vals);CHKERRQ(ierr);
66d4bb536fSBarry Smith     }
67d4bb536fSBarry Smith   } else {
6887828ca2SBarry Smith     ierr = PetscMalloc((n1+1)*sizeof(PetscScalar),&vals);CHKERRQ(ierr);
6906be10caSBarry Smith     for (i=start; i<end; i++) {
7090f02eecSBarry Smith       ierr = MatGetRow(X,i,&ncols,&row,&val);CHKERRQ(ierr);
7106be10caSBarry Smith       for (j=0; j<ncols; j++) {
7206be10caSBarry Smith 	vals[j] = (*a)*val[j];
736f79c3a4SBarry Smith       }
74dbb450caSBarry Smith       ierr = MatSetValues(Y,1,&i,ncols,row,vals,ADD_VALUES);CHKERRQ(ierr);
7590f02eecSBarry Smith       ierr = MatRestoreRow(X,i,&ncols,&row,&val);CHKERRQ(ierr);
766f79c3a4SBarry Smith     }
77606d414cSSatish Balay     ierr = PetscFree(vals);CHKERRQ(ierr);
78d4bb536fSBarry Smith   }
796d4a8577SBarry Smith   ierr = MatAssemblyBegin(Y,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
806d4a8577SBarry Smith   ierr = MatAssemblyEnd(Y,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
813a40ed3dSBarry Smith   PetscFunctionReturn(0);
826f79c3a4SBarry Smith }
83052efed2SBarry Smith 
844a2ae208SSatish Balay #undef __FUNCT__
854a2ae208SSatish Balay #define __FUNCT__ "MatShift"
86052efed2SBarry Smith /*@
8787828ca2SBarry Smith    MatShift - Computes Y =  Y + a I, where a is a PetscScalar and I is the identity matrix.
88052efed2SBarry Smith 
89fee21e36SBarry Smith    Collective on Mat
90fee21e36SBarry Smith 
9198a79cdbSBarry Smith    Input Parameters:
9298a79cdbSBarry Smith +  Y - the matrices
9387828ca2SBarry Smith -  a - the PetscScalar
9498a79cdbSBarry Smith 
952860a424SLois Curfman McInnes    Level: intermediate
962860a424SLois Curfman McInnes 
97052efed2SBarry Smith .keywords: matrix, add, shift
986b9ee512SLois Curfman McInnes 
99f56f2b3fSBarry Smith .seealso: MatDiagonalSet()
100052efed2SBarry Smith  @*/
10187828ca2SBarry Smith int MatShift(PetscScalar *a,Mat Y)
102052efed2SBarry Smith {
103052efed2SBarry Smith   int    i,start,end,ierr;
104052efed2SBarry Smith 
1053a40ed3dSBarry Smith   PetscFunctionBegin;
10677c4ece6SBarry Smith   PetscValidHeaderSpecific(Y,MAT_COOKIE);
10790f02eecSBarry Smith   PetscValidScalarPointer(a);
108f830108cSBarry Smith   if (Y->ops->shift) {
109f830108cSBarry Smith     ierr = (*Y->ops->shift)(a,Y);CHKERRQ(ierr);
11062d58ce1SBarry Smith   } else {
111d4bb536fSBarry Smith     ierr = MatGetOwnershipRange(Y,&start,&end);CHKERRQ(ierr);
112052efed2SBarry Smith     for (i=start; i<end; i++) {
113052efed2SBarry Smith       ierr = MatSetValues(Y,1,&i,1,&i,a,ADD_VALUES);CHKERRQ(ierr);
114052efed2SBarry Smith     }
1156d4a8577SBarry Smith     ierr = MatAssemblyBegin(Y,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
1166d4a8577SBarry Smith     ierr = MatAssemblyEnd(Y,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
117052efed2SBarry Smith   }
1183a40ed3dSBarry Smith   PetscFunctionReturn(0);
119052efed2SBarry Smith }
1206d84be18SBarry Smith 
1214a2ae208SSatish Balay #undef __FUNCT__
1224a2ae208SSatish Balay #define __FUNCT__ "MatDiagonalSet"
1236d84be18SBarry Smith /*@
124f56f2b3fSBarry Smith    MatDiagonalSet - Computes Y = Y + D, where D is a diagonal matrix
125f56f2b3fSBarry Smith    that is represented as a vector. Or Y[i,i] = D[i] if InsertMode is
126f56f2b3fSBarry Smith    INSERT_VALUES.
1276d84be18SBarry Smith 
1286d84be18SBarry Smith    Input Parameters:
12998a79cdbSBarry Smith +  Y - the input matrix
130f56f2b3fSBarry Smith .  D - the diagonal matrix, represented as a vector
131f56f2b3fSBarry Smith -  i - INSERT_VALUES or ADD_VALUES
1326d84be18SBarry Smith 
133fee21e36SBarry Smith    Collective on Mat and Vec
134fee21e36SBarry Smith 
1352860a424SLois Curfman McInnes    Level: intermediate
1362860a424SLois Curfman McInnes 
1376b9ee512SLois Curfman McInnes .keywords: matrix, add, shift, diagonal
1386b9ee512SLois Curfman McInnes 
1396b9ee512SLois Curfman McInnes .seealso: MatShift()
1406d84be18SBarry Smith @*/
141f56f2b3fSBarry Smith int MatDiagonalSet(Mat Y,Vec D,InsertMode is)
1426d84be18SBarry Smith {
1436d84be18SBarry Smith   int    i,start,end,ierr;
1446d84be18SBarry Smith 
1453a40ed3dSBarry Smith   PetscFunctionBegin;
14677c4ece6SBarry Smith   PetscValidHeaderSpecific(Y,MAT_COOKIE);
14790f02eecSBarry Smith   PetscValidHeaderSpecific(D,VEC_COOKIE);
148f56f2b3fSBarry Smith   if (Y->ops->diagonalset) {
149f56f2b3fSBarry Smith     ierr = (*Y->ops->diagonalset)(Y,D,is);CHKERRQ(ierr);
15094d884c6SBarry Smith   } else {
1516d84be18SBarry Smith     int    vstart,vend;
15287828ca2SBarry Smith     PetscScalar *v;
1536d84be18SBarry Smith     ierr = VecGetOwnershipRange(D,&vstart,&vend);CHKERRQ(ierr);
1546d84be18SBarry Smith     ierr = MatGetOwnershipRange(Y,&start,&end);CHKERRQ(ierr);
155d4bb536fSBarry Smith     if (vstart != start || vend != end) {
15629bbc08cSBarry Smith       SETERRQ4(PETSC_ERR_ARG_SIZ,"Vector ownership range not compatible with matrix: %d %d vec %d %d mat",vstart,vend,start,end);
157d4bb536fSBarry Smith     }
1586d84be18SBarry Smith     ierr = VecGetArray(D,&v);CHKERRQ(ierr);
1596d84be18SBarry Smith     for (i=start; i<end; i++) {
160f56f2b3fSBarry Smith       ierr = MatSetValues(Y,1,&i,1,&i,v+i-start,is);CHKERRQ(ierr);
1616d84be18SBarry Smith     }
1622e8a6d31SBarry Smith     ierr = VecRestoreArray(D,&v);CHKERRQ(ierr);
1636d4a8577SBarry Smith     ierr = MatAssemblyBegin(Y,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
1646d4a8577SBarry Smith     ierr = MatAssemblyEnd(Y,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
1656d84be18SBarry Smith   }
1663a40ed3dSBarry Smith   PetscFunctionReturn(0);
1676d84be18SBarry Smith }
168d4bb536fSBarry Smith 
1694a2ae208SSatish Balay #undef __FUNCT__
1704a2ae208SSatish Balay #define __FUNCT__ "MatAYPX"
171d4bb536fSBarry Smith /*@
172d4bb536fSBarry Smith    MatAYPX - Computes Y = X + a*Y.
173d4bb536fSBarry Smith 
174fee21e36SBarry Smith    Collective on Mat
175fee21e36SBarry Smith 
17698a79cdbSBarry Smith    Input Parameters:
17798a79cdbSBarry Smith +  X,Y - the matrices
17887828ca2SBarry Smith -  a - the PetscScalar multiplier
17998a79cdbSBarry Smith 
180e182c471SBarry Smith    Contributed by: Matthew Knepley
181d4bb536fSBarry Smith 
1822860a424SLois Curfman McInnes    Notes:
1832860a424SLois Curfman McInnes    This routine currently uses the MatAXPY() implementation.
1842860a424SLois Curfman McInnes 
185*607cd303SBarry Smith    This is slow, if you need it fast send email to petsc-maint@mcs.anl.gov
186*607cd303SBarry Smith 
1872860a424SLois Curfman McInnes    Level: intermediate
1882860a424SLois Curfman McInnes 
189d4bb536fSBarry Smith .keywords: matrix, add
190d4bb536fSBarry Smith 
1912860a424SLois Curfman McInnes .seealso: MatAXPY()
192d4bb536fSBarry Smith  @*/
19387828ca2SBarry Smith int MatAYPX(PetscScalar *a,Mat X,Mat Y)
194d4bb536fSBarry Smith {
19587828ca2SBarry Smith   PetscScalar one = 1.0;
196d4bb536fSBarry Smith   int         mX,mY,nX,nY,ierr;
197d4bb536fSBarry Smith 
1983a40ed3dSBarry Smith   PetscFunctionBegin;
199d4bb536fSBarry Smith   PetscValidHeaderSpecific(X,MAT_COOKIE);
200d4bb536fSBarry Smith   PetscValidHeaderSpecific(Y,MAT_COOKIE);
201d4bb536fSBarry Smith   PetscValidScalarPointer(a);
202d4bb536fSBarry Smith 
203329f5518SBarry Smith   ierr = MatGetSize(X,&mX,&nX);CHKERRQ(ierr);
204329f5518SBarry Smith   ierr = MatGetSize(X,&mY,&nY);CHKERRQ(ierr);
20529bbc08cSBarry Smith   if (mX != mY || nX != nY) SETERRQ4(PETSC_ERR_ARG_SIZ,"Non conforming matrices: %d %d first %d %d second",mX,mY,nX,nY);
206d4bb536fSBarry Smith 
207d4bb536fSBarry Smith   ierr = MatScale(a,Y);CHKERRQ(ierr);
208*607cd303SBarry Smith   ierr = MatAXPY(&one,X,Y,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr);
2093a40ed3dSBarry Smith   PetscFunctionReturn(0);
210d4bb536fSBarry Smith }
211b0a32e0cSBarry Smith 
2124a2ae208SSatish Balay #undef __FUNCT__
2134a2ae208SSatish Balay #define __FUNCT__ "MatComputeExplicitOperator"
214b0a32e0cSBarry Smith /*@
215b0a32e0cSBarry Smith     MatComputeExplicitOperator - Computes the explicit matrix
216b0a32e0cSBarry Smith 
217b0a32e0cSBarry Smith     Collective on Mat
218b0a32e0cSBarry Smith 
219b0a32e0cSBarry Smith     Input Parameter:
220b0a32e0cSBarry Smith .   inmat - the matrix
221b0a32e0cSBarry Smith 
222b0a32e0cSBarry Smith     Output Parameter:
223b0a32e0cSBarry Smith .   mat - the explict preconditioned operator
224b0a32e0cSBarry Smith 
225b0a32e0cSBarry Smith     Notes:
226b0a32e0cSBarry Smith     This computation is done by applying the operators to columns of the
227b0a32e0cSBarry Smith     identity matrix.
228b0a32e0cSBarry Smith 
229b0a32e0cSBarry Smith     Currently, this routine uses a dense matrix format when 1 processor
230b0a32e0cSBarry Smith     is used and a sparse format otherwise.  This routine is costly in general,
231b0a32e0cSBarry Smith     and is recommended for use only with relatively small systems.
232b0a32e0cSBarry Smith 
233b0a32e0cSBarry Smith     Level: advanced
234b0a32e0cSBarry Smith 
235b0a32e0cSBarry Smith .keywords: Mat, compute, explicit, operator
236b0a32e0cSBarry Smith 
237b0a32e0cSBarry Smith @*/
238b0a32e0cSBarry Smith int MatComputeExplicitOperator(Mat inmat,Mat *mat)
239b0a32e0cSBarry Smith {
240b0a32e0cSBarry Smith   Vec      in,out;
241b0a32e0cSBarry Smith   int      ierr,i,M,m,size,*rows,start,end;
242b0a32e0cSBarry Smith   MPI_Comm comm;
24387828ca2SBarry Smith   PetscScalar   *array,zero = 0.0,one = 1.0;
244b0a32e0cSBarry Smith 
245b0a32e0cSBarry Smith   PetscFunctionBegin;
246b0a32e0cSBarry Smith   PetscValidHeaderSpecific(inmat,MAT_COOKIE);
247b0a32e0cSBarry Smith   PetscValidPointer(mat);
248b0a32e0cSBarry Smith 
249b0a32e0cSBarry Smith   comm = inmat->comm;
250b0a32e0cSBarry Smith   ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
251b0a32e0cSBarry Smith 
252b22afee1SSatish Balay   ierr = MatGetLocalSize(inmat,&m,0);CHKERRQ(ierr);
253b22afee1SSatish Balay   ierr = MatGetSize(inmat,&M,0);CHKERRQ(ierr);
254b0a32e0cSBarry Smith   ierr = VecCreateMPI(comm,m,M,&in);CHKERRQ(ierr);
255b0a32e0cSBarry Smith   ierr = VecDuplicate(in,&out);CHKERRQ(ierr);
256b0a32e0cSBarry Smith   ierr = VecGetOwnershipRange(in,&start,&end);CHKERRQ(ierr);
257b0a32e0cSBarry Smith   ierr = PetscMalloc((m+1)*sizeof(int),&rows);CHKERRQ(ierr);
258b0a32e0cSBarry Smith   for (i=0; i<m; i++) {rows[i] = start + i;}
259b0a32e0cSBarry Smith 
260b0a32e0cSBarry Smith   if (size == 1) {
261b0a32e0cSBarry Smith     ierr = MatCreateSeqDense(comm,M,M,PETSC_NULL,mat);CHKERRQ(ierr);
262b0a32e0cSBarry Smith   } else {
263b0a32e0cSBarry Smith     ierr = MatCreateMPIAIJ(comm,m,m,M,M,0,0,0,0,mat);CHKERRQ(ierr);
264b0a32e0cSBarry Smith   }
265b0a32e0cSBarry Smith 
266b0a32e0cSBarry Smith   for (i=0; i<M; i++) {
267b0a32e0cSBarry Smith 
268b0a32e0cSBarry Smith     ierr = VecSet(&zero,in);CHKERRQ(ierr);
269b0a32e0cSBarry Smith     ierr = VecSetValues(in,1,&i,&one,INSERT_VALUES);CHKERRQ(ierr);
270b0a32e0cSBarry Smith     ierr = VecAssemblyBegin(in);CHKERRQ(ierr);
271b0a32e0cSBarry Smith     ierr = VecAssemblyEnd(in);CHKERRQ(ierr);
272b0a32e0cSBarry Smith 
273b0a32e0cSBarry Smith     ierr = MatMult(inmat,in,out);CHKERRQ(ierr);
274b0a32e0cSBarry Smith 
275b0a32e0cSBarry Smith     ierr = VecGetArray(out,&array);CHKERRQ(ierr);
276b0a32e0cSBarry Smith     ierr = MatSetValues(*mat,m,rows,1,&i,array,INSERT_VALUES);CHKERRQ(ierr);
277b0a32e0cSBarry Smith     ierr = VecRestoreArray(out,&array);CHKERRQ(ierr);
278b0a32e0cSBarry Smith 
279b0a32e0cSBarry Smith   }
280b0a32e0cSBarry Smith   ierr = PetscFree(rows);CHKERRQ(ierr);
281b0a32e0cSBarry Smith   ierr = VecDestroy(out);CHKERRQ(ierr);
282b0a32e0cSBarry Smith   ierr = VecDestroy(in);CHKERRQ(ierr);
283b0a32e0cSBarry Smith   ierr = MatAssemblyBegin(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
284b0a32e0cSBarry Smith   ierr = MatAssemblyEnd(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
285b0a32e0cSBarry Smith   PetscFunctionReturn(0);
286b0a32e0cSBarry Smith }
287b0a32e0cSBarry Smith 
288