#include "src/mat/matimpl.h" /*I "petscmat.h" I*/ #undef __FUNCT__ #define __FUNCT__ "MatAXPY" /*@ MatAXPY - Computes Y = a*X + Y. Collective on Mat Input Parameters: + a - the scalar multiplier . X - the first matrix . Y - the second matrix - str - either SAME_NONZERO_PATTERN, DIFFERENT_NONZERO_PATTERN or SUBSET_NONZERO_PATTERN Contributed by: Matthew Knepley Notes: Will only be efficient if one has the SAME_NONZERO_PATTERN or SUBSET_NONZERO_PATTERN Level: intermediate .keywords: matrix, add .seealso: MatAYPX() @*/ PetscErrorCode MatAXPY(const PetscScalar *a,Mat X,Mat Y,MatStructure str) { PetscErrorCode ierr; int m1,m2,n1,n2; PetscFunctionBegin; PetscValidScalarPointer(a,1); PetscValidHeaderSpecific(X,MAT_COOKIE,2); PetscValidHeaderSpecific(Y,MAT_COOKIE,3); ierr = MatGetSize(X,&m1,&n1);CHKERRQ(ierr); ierr = MatGetSize(Y,&m2,&n2);CHKERRQ(ierr); if (m1 != m2 || n1 != n2) SETERRQ4(PETSC_ERR_ARG_SIZ,"Non conforming matrix add: %d %d %d %d",m1,m2,n1,n2); if (X->ops->axpy) { ierr = (*X->ops->axpy)(a,X,Y,str);CHKERRQ(ierr); } else { ierr = MatAXPY_Basic(a,X,Y,str);CHKERRQ(ierr); } PetscFunctionReturn(0); } #undef __FUNCT__ #define __FUNCT__ "MatAXPY_Basic" PetscErrorCode MatAXPY_Basic(const PetscScalar *a,Mat X,Mat Y,MatStructure str) { int i,start,end,j,ncols,m,n; PetscErrorCode ierr; const int *row; PetscScalar *val; const PetscScalar *vals; PetscFunctionBegin; ierr = MatGetSize(X,&m,&n);CHKERRQ(ierr); ierr = MatGetOwnershipRange(X,&start,&end);CHKERRQ(ierr); if (*a == 1.0) { for (i = start; i < end; i++) { ierr = MatGetRow(X,i,&ncols,&row,&vals);CHKERRQ(ierr); ierr = MatSetValues(Y,1,&i,ncols,row,vals,ADD_VALUES);CHKERRQ(ierr); ierr = MatRestoreRow(X,i,&ncols,&row,&vals);CHKERRQ(ierr); } } else { ierr = PetscMalloc((n+1)*sizeof(PetscScalar),&val);CHKERRQ(ierr); for (i=start; iops->shift) { ierr = (*Y->ops->shift)(a,Y);CHKERRQ(ierr); } else { ierr = MatGetOwnershipRange(Y,&start,&end);CHKERRQ(ierr); for (i=start; iops->diagonalset) { ierr = (*Y->ops->diagonalset)(Y,D,is);CHKERRQ(ierr); } else { int vstart,vend; PetscScalar *v; ierr = VecGetOwnershipRange(D,&vstart,&vend);CHKERRQ(ierr); ierr = MatGetOwnershipRange(Y,&start,&end);CHKERRQ(ierr); if (vstart != start || vend != end) { SETERRQ4(PETSC_ERR_ARG_SIZ,"Vector ownership range not compatible with matrix: %d %d vec %d %d mat",vstart,vend,start,end); } ierr = VecGetArray(D,&v);CHKERRQ(ierr); for (i=start; icomm; ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); ierr = MatGetLocalSize(inmat,&m,0);CHKERRQ(ierr); ierr = MatGetSize(inmat,&M,0);CHKERRQ(ierr); ierr = VecCreateMPI(comm,m,M,&in);CHKERRQ(ierr); ierr = VecDuplicate(in,&out);CHKERRQ(ierr); ierr = VecGetOwnershipRange(in,&start,&end);CHKERRQ(ierr); ierr = PetscMalloc((m+1)*sizeof(int),&rows);CHKERRQ(ierr); for (i=0; i