/*@ MatShift - Computes Y = Y + a I, where a is a PetscScalar and I is the identity matrix. Neighbor-wise Collective on Mat Input Parameters: + Y - the matrices - a - the PetscScalar Level: intermediate .keywords: matrix, add, shift .seealso: MatDiagonalSet() @*/ PetscErrorCode MatShift(Mat Y,PetscScalar a) { PetscErrorCode ierr; PetscInt i,start,end; PetscFunctionBegin; PetscValidHeaderSpecific(Y,MAT_CLASSID,1); if (!Y->assembled) SETERRQ(PetscObjectComm((PetscObject)Y),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); if (Y->factortype) SETERRQ(PetscObjectComm((PetscObject)Y),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; i<end; i++) { ierr = MatSetValues(Y,1,&i,1,&i,&alpha,ADD_VALUES);CHKERRQ(ierr); } ierr = MatAssemblyBegin(Y,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(Y,MAT_FINAL_ASSEMBLY);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); }
/*@ MatShift - Computes Y = Y + a I, where a is a PetscScalar and I is the identity matrix. Neighbor-wise Collective on Mat Input Parameters: + Y - the matrices - a - the PetscScalar Level: intermediate Notes: If the matrix Y is missing some diagonal entries this routine can be very slow. To make it fast one should initially fill the matrix so that all diagonal entries have a value (with a value of zero for those locations that would not have an entry). Developers Note: If the local "diagonal part" of the matrix Y has no entries then the local diagonal part is preallocated with 1 nonzero per row for the to be added values. This allows for fast shifting of an empty matrix. .keywords: matrix, add, shift .seealso: MatDiagonalSet() @*/ PetscErrorCode MatShift(Mat Y,PetscScalar a) { PetscErrorCode ierr; PetscFunctionBegin; PetscValidHeaderSpecific(Y,MAT_CLASSID,1); if (!Y->assembled) SETERRQ(PetscObjectComm((PetscObject)Y),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); if (Y->factortype) SETERRQ(PetscObjectComm((PetscObject)Y),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); MatCheckPreallocated(Y,1); ierr = (*Y->ops->shift)(Y,a);CHKERRQ(ierr); #if defined(PETSC_HAVE_CUSP) if (Y->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) { Y->valid_GPU_matrix = PETSC_CUSP_CPU; } #elif defined(PETSC_HAVE_VIENNACL) if (Y->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) { Y->valid_GPU_matrix = PETSC_VIENNACL_CPU; } #elif defined(PETSC_HAVE_VECCUDA) if (Y->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) { Y->valid_GPU_matrix = PETSC_CUDA_CPU; } #endif PetscFunctionReturn(0); }