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