#include /*I "petscmat.h" I*/ #undef __FUNCT__ #define __FUNCT__ "MatAXPY" /*@ MatAXPY - Computes Y = a*X + Y. Logically 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 (nonzeros of X is a subset of Y's) Level: intermediate .keywords: matrix, add .seealso: MatAYPX() @*/ PetscErrorCode MatAXPY(Mat Y,PetscScalar a,Mat X,MatStructure str) { PetscErrorCode ierr; PetscInt m1,m2,n1,n2; PetscFunctionBegin; PetscValidHeaderSpecific(X,MAT_CLASSID,3); PetscValidHeaderSpecific(Y,MAT_CLASSID,1); PetscValidLogicalCollectiveScalar(Y,a,2); ierr = MatGetSize(X,&m1,&n1);CHKERRQ(ierr); ierr = MatGetSize(Y,&m2,&n2);CHKERRQ(ierr); if (m1 != m2 || n1 != n2) SETERRQ4(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Non conforming matrix add: %D %D %D %D",m1,m2,n1,n2); ierr = PetscLogEventBegin(MAT_AXPY,Y,0,0,0);CHKERRQ(ierr); if (Y->ops->axpy) { ierr = (*Y->ops->axpy)(Y,a,X,str);CHKERRQ(ierr); } else { ierr = MatAXPY_Basic(Y,a,X,str);CHKERRQ(ierr); } ierr = PetscLogEventEnd(MAT_AXPY,Y,0,0,0);CHKERRQ(ierr); #if defined(PETSC_HAVE_CUSP) if (Y->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) { Y->valid_GPU_matrix = PETSC_CUSP_CPU; } #endif PetscFunctionReturn(0); } #undef __FUNCT__ #define __FUNCT__ "MatAXPY_Basic" PetscErrorCode MatAXPY_Basic(Mat Y,PetscScalar a,Mat X,MatStructure str) { PetscInt i,start,end,j,ncols,m,n; PetscErrorCode ierr; const PetscInt *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; iassembled) SETERRQ(((PetscObject)Y)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); if (Y->factortype) SETERRQ(((PetscObject)Y)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); MatCheckPreallocated(Y,1); if (Y->ops->shift) { ierr = (*Y->ops->shift)(Y,a);CHKERRQ(ierr); } else { PetscScalar alpha = a; ierr = MatGetOwnershipRange(Y,&start,&end);CHKERRQ(ierr); for (i=start; ivalid_GPU_matrix != PETSC_CUSP_UNALLOCATED) { Y->valid_GPU_matrix = PETSC_CUSP_CPU; } #endif PetscFunctionReturn(0); } #undef __FUNCT__ #define __FUNCT__ "MatDiagonalSet_Default" PetscErrorCode MatDiagonalSet_Default(Mat Y,Vec D,InsertMode is) { PetscErrorCode ierr; PetscInt i,start,end,vstart,vend; PetscScalar *v; PetscFunctionBegin; ierr = VecGetOwnershipRange(D,&vstart,&vend);CHKERRQ(ierr); ierr = MatGetOwnershipRange(Y,&start,&end);CHKERRQ(ierr); if (vstart != start || vend != end) SETERRQ4(PETSC_COMM_SELF,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; iops->diagonalset) { ierr = (*Y->ops->diagonalset)(Y,D,is);CHKERRQ(ierr); } else { ierr = MatDiagonalSet_Default(Y,D,is);CHKERRQ(ierr); } PetscFunctionReturn(0); } #undef __FUNCT__ #define __FUNCT__ "MatAYPX" /*@ MatAYPX - Computes Y = a*Y + X. Logically on Mat Input Parameters: + a - the PetscScalar multiplier . Y - the first matrix . X - the second matrix - str - either SAME_NONZERO_PATTERN, DIFFERENT_NONZERO_PATTERN or SUBSET_NONZERO_PATTERN Level: intermediate .keywords: matrix, add .seealso: MatAXPY() @*/ PetscErrorCode MatAYPX(Mat Y,PetscScalar a,Mat X,MatStructure str) { PetscScalar one = 1.0; PetscErrorCode ierr; PetscInt mX,mY,nX,nY; PetscFunctionBegin; PetscValidHeaderSpecific(X,MAT_CLASSID,3); PetscValidHeaderSpecific(Y,MAT_CLASSID,1); PetscValidLogicalCollectiveScalar(Y,a,2); ierr = MatGetSize(X,&mX,&nX);CHKERRQ(ierr); ierr = MatGetSize(X,&mY,&nY);CHKERRQ(ierr); if (mX != mY || nX != nY) SETERRQ4(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Non conforming matrices: %D %D first %D %D second",mX,mY,nX,nY); ierr = MatScale(Y,a);CHKERRQ(ierr); ierr = MatAXPY(Y,one,X,str);CHKERRQ(ierr); PetscFunctionReturn(0); } #undef __FUNCT__ #define __FUNCT__ "MatComputeExplicitOperator" /*@ MatComputeExplicitOperator - Computes the explicit matrix Collective on Mat Input Parameter: . inmat - the matrix Output Parameter: . mat - the explict preconditioned operator Notes: This computation is done by applying the operators to columns of the identity matrix. Currently, this routine uses a dense matrix format when 1 processor is used and a sparse format otherwise. This routine is costly in general, and is recommended for use only with relatively small systems. Level: advanced .keywords: Mat, compute, explicit, operator @*/ PetscErrorCode MatComputeExplicitOperator(Mat inmat,Mat *mat) { Vec in,out; PetscErrorCode ierr; PetscInt i,m,n,M,N,*rows,start,end; MPI_Comm comm; PetscScalar *array,zero = 0.0,one = 1.0; PetscMPIInt size; PetscFunctionBegin; PetscValidHeaderSpecific(inmat,MAT_CLASSID,1); PetscValidPointer(mat,2); comm = ((PetscObject)inmat)->comm; ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); ierr = MatGetLocalSize(inmat,&m,&n);CHKERRQ(ierr); ierr = MatGetSize(inmat,&M,&N);CHKERRQ(ierr); ierr = MatGetVecs(inmat,&in,&out);CHKERRQ(ierr); ierr = VecSetOption(in,VEC_IGNORE_OFF_PROC_ENTRIES,PETSC_TRUE);CHKERRQ(ierr); ierr = VecGetOwnershipRange(out,&start,&end);CHKERRQ(ierr); ierr = PetscMalloc(m*sizeof(PetscInt),&rows);CHKERRQ(ierr); for (i=0; i