#include /*I "petsctao.h" I*/ #include #include #include /* For finited difference computations of the Hessian, we use PETSc's SNESComputeJacobianDefault */ static PetscErrorCode Fsnes(SNES snes,Vec X,Vec G,void* ctx) { PetscErrorCode ierr; Tao tao = (Tao)ctx; PetscFunctionBegin; PetscValidHeaderSpecific(tao,TAO_CLASSID,4); ierr = TaoComputeGradient(tao,X,G);CHKERRQ(ierr); PetscFunctionReturn(0); } /*@C TaoDefaultComputeGradient - computes the gradient using finite differences. Collective on Tao Input Parameters: + tao - the Tao context . X - compute gradient at this point - dummy - not used Output Parameter: . G - Gradient Vector Options Database Key: + -tao_fd_gradient - activates TaoDefaultComputeGradient() - -tao_fd_delta - change in X used to calculate finite differences Level: advanced Notes: This routine is slow and expensive, and is not currently optimized to take advantage of sparsity in the problem. Although TaoDefaultComputeGradient is not recommended for general use in large-scale applications, It can be useful in checking the correctness of a user-provided gradient. Use the tao method TAOTEST to get an indication of whether your gradient is correct. This finite difference gradient evaluation can be set using the routine TaoSetGradientRoutine() or by using the command line option -tao_fd_gradient .seealso: TaoSetGradientRoutine() @*/ PetscErrorCode TaoDefaultComputeGradient(Tao tao,Vec Xin,Vec G,void *dummy) { Vec X; PetscScalar *g; PetscReal f, f2; PetscErrorCode ierr; PetscInt low,high,N,i; PetscBool flg; PetscReal h=.5*PETSC_SQRT_MACHINE_EPSILON; PetscFunctionBegin; ierr = PetscOptionsGetReal(((PetscObject)tao)->options,((PetscObject)tao)->prefix,"-tao_fd_delta",&h,&flg);CHKERRQ(ierr); ierr = VecDuplicate(Xin,&X);CHKERRQ(ierr); ierr = VecCopy(Xin,X);CHKERRQ(ierr); ierr = VecGetSize(X,&N);CHKERRQ(ierr); ierr = VecGetOwnershipRange(X,&low,&high);CHKERRQ(ierr); ierr = VecSetOption(X,VEC_IGNORE_OFF_PROC_ENTRIES,PETSC_TRUE);CHKERRQ(ierr); ierr = VecGetArray(G,&g);CHKERRQ(ierr); for (i=0;i=low && i