xref: /petsc/src/mat/utils/axpy.c (revision b0a32e0c6855ee6a6cd3495fa7da12ea9885bc5d)
1*b0a32e0cSBarry Smith /*$Id: axpy.c,v 1.49 2000/10/24 20:26:14 bsmith Exp bsmith $*/
26f79c3a4SBarry Smith 
3e090d566SSatish Balay #include "src/mat/matimpl.h"  /*I   "petscmat.h"  I*/
46f79c3a4SBarry Smith 
55615d1e5SSatish Balay #undef __FUNC__
6*b0a32e0cSBarry Smith #define __FUNC__ "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 {
53*b0a32e0cSBarry 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 
705615d1e5SSatish Balay #undef __FUNC__
71*b0a32e0cSBarry Smith #define __FUNC__ "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 
1075615d1e5SSatish Balay #undef __FUNC__
108*b0a32e0cSBarry Smith #define __FUNC__ "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 
155d4bb536fSBarry Smith #undef __FUNC__
156*b0a32e0cSBarry Smith #define __FUNC__ "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 }
195*b0a32e0cSBarry Smith 
196*b0a32e0cSBarry Smith #undef __FUNC__
197*b0a32e0cSBarry Smith #define __FUNC__ "MatComputeExplicitOperator"
198*b0a32e0cSBarry Smith /*@
199*b0a32e0cSBarry Smith     MatComputeExplicitOperator - Computes the explicit matrix
200*b0a32e0cSBarry Smith 
201*b0a32e0cSBarry Smith     Collective on Mat
202*b0a32e0cSBarry Smith 
203*b0a32e0cSBarry Smith     Input Parameter:
204*b0a32e0cSBarry Smith .   inmat - the matrix
205*b0a32e0cSBarry Smith 
206*b0a32e0cSBarry Smith     Output Parameter:
207*b0a32e0cSBarry Smith .   mat - the explict preconditioned operator
208*b0a32e0cSBarry Smith 
209*b0a32e0cSBarry Smith     Notes:
210*b0a32e0cSBarry Smith     This computation is done by applying the operators to columns of the
211*b0a32e0cSBarry Smith     identity matrix.
212*b0a32e0cSBarry Smith 
213*b0a32e0cSBarry Smith     Currently, this routine uses a dense matrix format when 1 processor
214*b0a32e0cSBarry Smith     is used and a sparse format otherwise.  This routine is costly in general,
215*b0a32e0cSBarry Smith     and is recommended for use only with relatively small systems.
216*b0a32e0cSBarry Smith 
217*b0a32e0cSBarry Smith     Level: advanced
218*b0a32e0cSBarry Smith 
219*b0a32e0cSBarry Smith .keywords: Mat, compute, explicit, operator
220*b0a32e0cSBarry Smith 
221*b0a32e0cSBarry Smith @*/
222*b0a32e0cSBarry Smith int MatComputeExplicitOperator(Mat inmat,Mat *mat)
223*b0a32e0cSBarry Smith {
224*b0a32e0cSBarry Smith   Vec      in,out;
225*b0a32e0cSBarry Smith   int      ierr,i,M,m,size,*rows,start,end;
226*b0a32e0cSBarry Smith   MPI_Comm comm;
227*b0a32e0cSBarry Smith   Scalar   *array,zero = 0.0,one = 1.0;
228*b0a32e0cSBarry Smith 
229*b0a32e0cSBarry Smith   PetscFunctionBegin;
230*b0a32e0cSBarry Smith   PetscValidHeaderSpecific(inmat,MAT_COOKIE);
231*b0a32e0cSBarry Smith   PetscValidPointer(mat);
232*b0a32e0cSBarry Smith 
233*b0a32e0cSBarry Smith   comm = inmat->comm;
234*b0a32e0cSBarry Smith   ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
235*b0a32e0cSBarry Smith 
236*b0a32e0cSBarry Smith   ierr = MatGetLocalSize(inmat,&m,0);
237*b0a32e0cSBarry Smith   ierr = MatGetSize(inmat,&M,0);
238*b0a32e0cSBarry Smith   ierr = VecCreateMPI(comm,m,M,&in);CHKERRQ(ierr);
239*b0a32e0cSBarry Smith   ierr = VecDuplicate(in,&out);CHKERRQ(ierr);
240*b0a32e0cSBarry Smith   ierr = VecGetOwnershipRange(in,&start,&end);CHKERRQ(ierr);
241*b0a32e0cSBarry Smith ierr = PetscMalloc((m+1)*sizeof(int),&  rows );CHKERRQ(ierr);
242*b0a32e0cSBarry Smith   for (i=0; i<m; i++) {rows[i] = start + i;}
243*b0a32e0cSBarry Smith 
244*b0a32e0cSBarry Smith   if (size == 1) {
245*b0a32e0cSBarry Smith     ierr = MatCreateSeqDense(comm,M,M,PETSC_NULL,mat);CHKERRQ(ierr);
246*b0a32e0cSBarry Smith   } else {
247*b0a32e0cSBarry Smith     ierr = MatCreateMPIAIJ(comm,m,m,M,M,0,0,0,0,mat);CHKERRQ(ierr);
248*b0a32e0cSBarry Smith   }
249*b0a32e0cSBarry Smith 
250*b0a32e0cSBarry Smith   for (i=0; i<M; i++) {
251*b0a32e0cSBarry Smith 
252*b0a32e0cSBarry Smith     ierr = VecSet(&zero,in);CHKERRQ(ierr);
253*b0a32e0cSBarry Smith     ierr = VecSetValues(in,1,&i,&one,INSERT_VALUES);CHKERRQ(ierr);
254*b0a32e0cSBarry Smith     ierr = VecAssemblyBegin(in);CHKERRQ(ierr);
255*b0a32e0cSBarry Smith     ierr = VecAssemblyEnd(in);CHKERRQ(ierr);
256*b0a32e0cSBarry Smith 
257*b0a32e0cSBarry Smith     ierr = MatMult(inmat,in,out);CHKERRQ(ierr);
258*b0a32e0cSBarry Smith 
259*b0a32e0cSBarry Smith     ierr = VecGetArray(out,&array);CHKERRQ(ierr);
260*b0a32e0cSBarry Smith     ierr = MatSetValues(*mat,m,rows,1,&i,array,INSERT_VALUES);CHKERRQ(ierr);
261*b0a32e0cSBarry Smith     ierr = VecRestoreArray(out,&array);CHKERRQ(ierr);
262*b0a32e0cSBarry Smith 
263*b0a32e0cSBarry Smith   }
264*b0a32e0cSBarry Smith   ierr = PetscFree(rows);CHKERRQ(ierr);
265*b0a32e0cSBarry Smith   ierr = VecDestroy(out);CHKERRQ(ierr);
266*b0a32e0cSBarry Smith   ierr = VecDestroy(in);CHKERRQ(ierr);
267*b0a32e0cSBarry Smith   ierr = MatAssemblyBegin(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
268*b0a32e0cSBarry Smith   ierr = MatAssemblyEnd(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
269*b0a32e0cSBarry Smith   PetscFunctionReturn(0);
270*b0a32e0cSBarry Smith }
271*b0a32e0cSBarry Smith 
272