xref: /petsc/src/mat/utils/axpy.c (revision 4a2ae208534dc2960f861bf8a1e27d424854347f)
1*4a2ae208SSatish Balay /*$Id: axpy.c,v 1.52 2001/03/09 19:38:01 balay Exp balay $*/
26f79c3a4SBarry Smith 
3e090d566SSatish Balay #include "src/mat/matimpl.h"  /*I   "petscmat.h"  I*/
46f79c3a4SBarry Smith 
5*4a2ae208SSatish Balay #undef __FUNCT__
6*4a2ae208SSatish 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:
1398a79cdbSBarry Smith +  X, Y - the matrices
1498a79cdbSBarry Smith -  a - the scalar multiplier
1598a79cdbSBarry Smith 
16e182c471SBarry Smith    Contributed by: Matthew Knepley
17d4bb536fSBarry Smith 
182860a424SLois Curfman McInnes    Notes:
192860a424SLois Curfman McInnes    Since the current implementation of MatAXPY() uses MatGetRow() to access
202860a424SLois Curfman McInnes    matrix data, efficiency is somewhat limited.
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  @*/
2806be10caSBarry Smith int MatAXPY(Scalar *a,Mat X,Mat Y)
296f79c3a4SBarry Smith {
3006be10caSBarry Smith   int    m1,m2,n1,n2,i,*row,start,end,j,ncols,ierr;
3106be10caSBarry Smith   Scalar *val,*vals;
326f79c3a4SBarry Smith 
333a40ed3dSBarry Smith   PetscFunctionBegin;
34d4bb536fSBarry Smith   PetscValidHeaderSpecific(X,MAT_COOKIE);
35d4bb536fSBarry Smith   PetscValidHeaderSpecific(Y,MAT_COOKIE);
3690f02eecSBarry Smith   PetscValidScalarPointer(a);
3790f02eecSBarry Smith 
38273d9f13SBarry Smith   ierr = MatGetSize(X,&m1,&n1);CHKERRQ(ierr);
39273d9f13SBarry Smith   ierr = MatGetSize(Y,&m2,&n2);CHKERRQ(ierr);
4029bbc08cSBarry Smith   if (m1 != m2 || n1 != n2) SETERRQ4(PETSC_ERR_ARG_SIZ,"Non conforming matrix add: %d %d %d %d",m1,m2,n1,n2);
411987afe7SBarry Smith 
42f830108cSBarry Smith   if (X->ops->axpy) {
43f830108cSBarry Smith     ierr = (*X->ops->axpy)(a,X,Y);CHKERRQ(ierr);
44d4bb536fSBarry Smith   } else {
4590f02eecSBarry Smith     ierr = MatGetOwnershipRange(X,&start,&end);CHKERRQ(ierr);
46d4bb536fSBarry Smith     if (*a == 1.0) {
47d4bb536fSBarry Smith       for (i = start; i < end; i++) {
48d4bb536fSBarry Smith         ierr = MatGetRow(X,i,&ncols,&row,&vals);CHKERRQ(ierr);
49d4bb536fSBarry Smith         ierr = MatSetValues(Y,1,&i,ncols,row,vals,ADD_VALUES);CHKERRQ(ierr);
50d4bb536fSBarry Smith         ierr = MatRestoreRow(X,i,&ncols,&row,&vals);CHKERRQ(ierr);
51d4bb536fSBarry Smith       }
52d4bb536fSBarry Smith     } else {
53b0a32e0cSBarry Smith       ierr = PetscMalloc((n1+1)*sizeof(Scalar),&vals);CHKERRQ(ierr);
5406be10caSBarry Smith       for (i=start; i<end; i++) {
5590f02eecSBarry Smith         ierr = MatGetRow(X,i,&ncols,&row,&val);CHKERRQ(ierr);
5606be10caSBarry Smith         for (j=0; j<ncols; j++) {
5706be10caSBarry Smith           vals[j] = (*a)*val[j];
586f79c3a4SBarry Smith         }
59dbb450caSBarry Smith         ierr = MatSetValues(Y,1,&i,ncols,row,vals,ADD_VALUES);CHKERRQ(ierr);
6090f02eecSBarry Smith         ierr = MatRestoreRow(X,i,&ncols,&row,&val);CHKERRQ(ierr);
616f79c3a4SBarry Smith       }
62606d414cSSatish Balay       ierr = PetscFree(vals);CHKERRQ(ierr);
63d4bb536fSBarry Smith     }
646d4a8577SBarry Smith     ierr = MatAssemblyBegin(Y,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
656d4a8577SBarry Smith     ierr = MatAssemblyEnd(Y,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
661987afe7SBarry Smith   }
673a40ed3dSBarry Smith   PetscFunctionReturn(0);
686f79c3a4SBarry Smith }
69052efed2SBarry Smith 
70*4a2ae208SSatish Balay #undef __FUNCT__
71*4a2ae208SSatish Balay #define __FUNCT__ "MatShift"
72052efed2SBarry Smith /*@
732860a424SLois Curfman McInnes    MatShift - Computes Y =  Y + a I, where a is a scalar and I is the identity matrix.
74052efed2SBarry Smith 
75fee21e36SBarry Smith    Collective on Mat
76fee21e36SBarry Smith 
7798a79cdbSBarry Smith    Input Parameters:
7898a79cdbSBarry Smith +  Y - the matrices
7998a79cdbSBarry Smith -  a - the scalar
8098a79cdbSBarry Smith 
812860a424SLois Curfman McInnes    Level: intermediate
822860a424SLois Curfman McInnes 
83052efed2SBarry Smith .keywords: matrix, add, shift
846b9ee512SLois Curfman McInnes 
85f56f2b3fSBarry Smith .seealso: MatDiagonalSet()
86052efed2SBarry Smith  @*/
87052efed2SBarry Smith int MatShift(Scalar *a,Mat Y)
88052efed2SBarry Smith {
89052efed2SBarry Smith   int    i,start,end,ierr;
90052efed2SBarry Smith 
913a40ed3dSBarry Smith   PetscFunctionBegin;
9277c4ece6SBarry Smith   PetscValidHeaderSpecific(Y,MAT_COOKIE);
9390f02eecSBarry Smith   PetscValidScalarPointer(a);
94f830108cSBarry Smith   if (Y->ops->shift) {
95f830108cSBarry Smith     ierr = (*Y->ops->shift)(a,Y);CHKERRQ(ierr);
9662d58ce1SBarry Smith   } else {
97d4bb536fSBarry Smith     ierr = MatGetOwnershipRange(Y,&start,&end);CHKERRQ(ierr);
98052efed2SBarry Smith     for (i=start; i<end; i++) {
99052efed2SBarry Smith       ierr = MatSetValues(Y,1,&i,1,&i,a,ADD_VALUES);CHKERRQ(ierr);
100052efed2SBarry Smith     }
1016d4a8577SBarry Smith     ierr = MatAssemblyBegin(Y,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
1026d4a8577SBarry Smith     ierr = MatAssemblyEnd(Y,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
103052efed2SBarry Smith   }
1043a40ed3dSBarry Smith   PetscFunctionReturn(0);
105052efed2SBarry Smith }
1066d84be18SBarry Smith 
107*4a2ae208SSatish Balay #undef __FUNCT__
108*4a2ae208SSatish Balay #define __FUNCT__ "MatDiagonalSet"
1096d84be18SBarry Smith /*@
110f56f2b3fSBarry Smith    MatDiagonalSet - Computes Y = Y + D, where D is a diagonal matrix
111f56f2b3fSBarry Smith    that is represented as a vector. Or Y[i,i] = D[i] if InsertMode is
112f56f2b3fSBarry Smith    INSERT_VALUES.
1136d84be18SBarry Smith 
1146d84be18SBarry Smith    Input Parameters:
11598a79cdbSBarry Smith +  Y - the input matrix
116f56f2b3fSBarry Smith .  D - the diagonal matrix, represented as a vector
117f56f2b3fSBarry Smith -  i - INSERT_VALUES or ADD_VALUES
1186d84be18SBarry Smith 
119fee21e36SBarry Smith    Collective on Mat and Vec
120fee21e36SBarry Smith 
1212860a424SLois Curfman McInnes    Level: intermediate
1222860a424SLois Curfman McInnes 
1236b9ee512SLois Curfman McInnes .keywords: matrix, add, shift, diagonal
1246b9ee512SLois Curfman McInnes 
1256b9ee512SLois Curfman McInnes .seealso: MatShift()
1266d84be18SBarry Smith @*/
127f56f2b3fSBarry Smith int MatDiagonalSet(Mat Y,Vec D,InsertMode is)
1286d84be18SBarry Smith {
1296d84be18SBarry Smith   int    i,start,end,ierr;
1306d84be18SBarry Smith 
1313a40ed3dSBarry Smith   PetscFunctionBegin;
13277c4ece6SBarry Smith   PetscValidHeaderSpecific(Y,MAT_COOKIE);
13390f02eecSBarry Smith   PetscValidHeaderSpecific(D,VEC_COOKIE);
134f56f2b3fSBarry Smith   if (Y->ops->diagonalset) {
135f56f2b3fSBarry Smith     ierr = (*Y->ops->diagonalset)(Y,D,is);CHKERRQ(ierr);
13694d884c6SBarry Smith   } else {
1376d84be18SBarry Smith     int    vstart,vend;
1386d84be18SBarry Smith     Scalar *v;
1396d84be18SBarry Smith     ierr = VecGetOwnershipRange(D,&vstart,&vend);CHKERRQ(ierr);
1406d84be18SBarry Smith     ierr = MatGetOwnershipRange(Y,&start,&end);CHKERRQ(ierr);
141d4bb536fSBarry Smith     if (vstart != start || vend != end) {
14229bbc08cSBarry Smith       SETERRQ4(PETSC_ERR_ARG_SIZ,"Vector ownership range not compatible with matrix: %d %d vec %d %d mat",vstart,vend,start,end);
143d4bb536fSBarry Smith     }
1446d84be18SBarry Smith     ierr = VecGetArray(D,&v);CHKERRQ(ierr);
1456d84be18SBarry Smith     for (i=start; i<end; i++) {
146f56f2b3fSBarry Smith       ierr = MatSetValues(Y,1,&i,1,&i,v+i-start,is);CHKERRQ(ierr);
1476d84be18SBarry Smith     }
1482e8a6d31SBarry Smith     ierr = VecRestoreArray(D,&v);CHKERRQ(ierr);
1496d4a8577SBarry Smith     ierr = MatAssemblyBegin(Y,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
1506d4a8577SBarry Smith     ierr = MatAssemblyEnd(Y,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
1516d84be18SBarry Smith   }
1523a40ed3dSBarry Smith   PetscFunctionReturn(0);
1536d84be18SBarry Smith }
154d4bb536fSBarry Smith 
155*4a2ae208SSatish Balay #undef __FUNCT__
156*4a2ae208SSatish Balay #define __FUNCT__ "MatAYPX"
157d4bb536fSBarry Smith /*@
158d4bb536fSBarry Smith    MatAYPX - Computes Y = X + a*Y.
159d4bb536fSBarry Smith 
160fee21e36SBarry Smith    Collective on Mat
161fee21e36SBarry Smith 
16298a79cdbSBarry Smith    Input Parameters:
16398a79cdbSBarry Smith +  X,Y - the matrices
16498a79cdbSBarry Smith -  a - the scalar multiplier
16598a79cdbSBarry Smith 
166e182c471SBarry Smith    Contributed by: Matthew Knepley
167d4bb536fSBarry Smith 
1682860a424SLois Curfman McInnes    Notes:
1692860a424SLois Curfman McInnes    This routine currently uses the MatAXPY() implementation.
1702860a424SLois Curfman McInnes 
1712860a424SLois Curfman McInnes    Level: intermediate
1722860a424SLois Curfman McInnes 
173d4bb536fSBarry Smith .keywords: matrix, add
174d4bb536fSBarry Smith 
1752860a424SLois Curfman McInnes .seealso: MatAXPY()
176d4bb536fSBarry Smith  @*/
177d4bb536fSBarry Smith int MatAYPX(Scalar *a,Mat X,Mat Y)
178d4bb536fSBarry Smith {
179d4bb536fSBarry Smith   Scalar one = 1.0;
180d4bb536fSBarry Smith   int    mX,mY,nX,nY,ierr;
181d4bb536fSBarry Smith 
1823a40ed3dSBarry Smith   PetscFunctionBegin;
183d4bb536fSBarry Smith   PetscValidHeaderSpecific(X,MAT_COOKIE);
184d4bb536fSBarry Smith   PetscValidHeaderSpecific(Y,MAT_COOKIE);
185d4bb536fSBarry Smith   PetscValidScalarPointer(a);
186d4bb536fSBarry Smith 
187329f5518SBarry Smith   ierr = MatGetSize(X,&mX,&nX);CHKERRQ(ierr);
188329f5518SBarry Smith   ierr = MatGetSize(X,&mY,&nY);CHKERRQ(ierr);
18929bbc08cSBarry Smith   if (mX != mY || nX != nY) SETERRQ4(PETSC_ERR_ARG_SIZ,"Non conforming matrices: %d %d first %d %d second",mX,mY,nX,nY);
190d4bb536fSBarry Smith 
191d4bb536fSBarry Smith   ierr = MatScale(a,Y);CHKERRQ(ierr);
192d4bb536fSBarry Smith   ierr = MatAXPY(&one,X,Y);CHKERRQ(ierr);
1933a40ed3dSBarry Smith   PetscFunctionReturn(0);
194d4bb536fSBarry Smith }
195b0a32e0cSBarry Smith 
196*4a2ae208SSatish Balay #undef __FUNCT__
197*4a2ae208SSatish Balay #define __FUNCT__ "MatComputeExplicitOperator"
198b0a32e0cSBarry Smith /*@
199b0a32e0cSBarry Smith     MatComputeExplicitOperator - Computes the explicit matrix
200b0a32e0cSBarry Smith 
201b0a32e0cSBarry Smith     Collective on Mat
202b0a32e0cSBarry Smith 
203b0a32e0cSBarry Smith     Input Parameter:
204b0a32e0cSBarry Smith .   inmat - the matrix
205b0a32e0cSBarry Smith 
206b0a32e0cSBarry Smith     Output Parameter:
207b0a32e0cSBarry Smith .   mat - the explict preconditioned operator
208b0a32e0cSBarry Smith 
209b0a32e0cSBarry Smith     Notes:
210b0a32e0cSBarry Smith     This computation is done by applying the operators to columns of the
211b0a32e0cSBarry Smith     identity matrix.
212b0a32e0cSBarry Smith 
213b0a32e0cSBarry Smith     Currently, this routine uses a dense matrix format when 1 processor
214b0a32e0cSBarry Smith     is used and a sparse format otherwise.  This routine is costly in general,
215b0a32e0cSBarry Smith     and is recommended for use only with relatively small systems.
216b0a32e0cSBarry Smith 
217b0a32e0cSBarry Smith     Level: advanced
218b0a32e0cSBarry Smith 
219b0a32e0cSBarry Smith .keywords: Mat, compute, explicit, operator
220b0a32e0cSBarry Smith 
221b0a32e0cSBarry Smith @*/
222b0a32e0cSBarry Smith int MatComputeExplicitOperator(Mat inmat,Mat *mat)
223b0a32e0cSBarry Smith {
224b0a32e0cSBarry Smith   Vec      in,out;
225b0a32e0cSBarry Smith   int      ierr,i,M,m,size,*rows,start,end;
226b0a32e0cSBarry Smith   MPI_Comm comm;
227b0a32e0cSBarry Smith   Scalar   *array,zero = 0.0,one = 1.0;
228b0a32e0cSBarry Smith 
229b0a32e0cSBarry Smith   PetscFunctionBegin;
230b0a32e0cSBarry Smith   PetscValidHeaderSpecific(inmat,MAT_COOKIE);
231b0a32e0cSBarry Smith   PetscValidPointer(mat);
232b0a32e0cSBarry Smith 
233b0a32e0cSBarry Smith   comm = inmat->comm;
234b0a32e0cSBarry Smith   ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
235b0a32e0cSBarry Smith 
236b22afee1SSatish Balay   ierr = MatGetLocalSize(inmat,&m,0);CHKERRQ(ierr);
237b22afee1SSatish Balay   ierr = MatGetSize(inmat,&M,0);CHKERRQ(ierr);
238b0a32e0cSBarry Smith   ierr = VecCreateMPI(comm,m,M,&in);CHKERRQ(ierr);
239b0a32e0cSBarry Smith   ierr = VecDuplicate(in,&out);CHKERRQ(ierr);
240b0a32e0cSBarry Smith   ierr = VecGetOwnershipRange(in,&start,&end);CHKERRQ(ierr);
241b0a32e0cSBarry Smith   ierr = PetscMalloc((m+1)*sizeof(int),&rows);CHKERRQ(ierr);
242b0a32e0cSBarry Smith   for (i=0; i<m; i++) {rows[i] = start + i;}
243b0a32e0cSBarry Smith 
244b0a32e0cSBarry Smith   if (size == 1) {
245b0a32e0cSBarry Smith     ierr = MatCreateSeqDense(comm,M,M,PETSC_NULL,mat);CHKERRQ(ierr);
246b0a32e0cSBarry Smith   } else {
247b0a32e0cSBarry Smith     ierr = MatCreateMPIAIJ(comm,m,m,M,M,0,0,0,0,mat);CHKERRQ(ierr);
248b0a32e0cSBarry Smith   }
249b0a32e0cSBarry Smith 
250b0a32e0cSBarry Smith   for (i=0; i<M; i++) {
251b0a32e0cSBarry Smith 
252b0a32e0cSBarry Smith     ierr = VecSet(&zero,in);CHKERRQ(ierr);
253b0a32e0cSBarry Smith     ierr = VecSetValues(in,1,&i,&one,INSERT_VALUES);CHKERRQ(ierr);
254b0a32e0cSBarry Smith     ierr = VecAssemblyBegin(in);CHKERRQ(ierr);
255b0a32e0cSBarry Smith     ierr = VecAssemblyEnd(in);CHKERRQ(ierr);
256b0a32e0cSBarry Smith 
257b0a32e0cSBarry Smith     ierr = MatMult(inmat,in,out);CHKERRQ(ierr);
258b0a32e0cSBarry Smith 
259b0a32e0cSBarry Smith     ierr = VecGetArray(out,&array);CHKERRQ(ierr);
260b0a32e0cSBarry Smith     ierr = MatSetValues(*mat,m,rows,1,&i,array,INSERT_VALUES);CHKERRQ(ierr);
261b0a32e0cSBarry Smith     ierr = VecRestoreArray(out,&array);CHKERRQ(ierr);
262b0a32e0cSBarry Smith 
263b0a32e0cSBarry Smith   }
264b0a32e0cSBarry Smith   ierr = PetscFree(rows);CHKERRQ(ierr);
265b0a32e0cSBarry Smith   ierr = VecDestroy(out);CHKERRQ(ierr);
266b0a32e0cSBarry Smith   ierr = VecDestroy(in);CHKERRQ(ierr);
267b0a32e0cSBarry Smith   ierr = MatAssemblyBegin(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
268b0a32e0cSBarry Smith   ierr = MatAssemblyEnd(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
269b0a32e0cSBarry Smith   PetscFunctionReturn(0);
270b0a32e0cSBarry Smith }
271b0a32e0cSBarry Smith 
272