1*a7e14dcfSSatish Balay #include "taosolver.h" /*I "taosolver.h" I*/ 2*a7e14dcfSSatish Balay #include "tao-private/taosolver_impl.h" 3*a7e14dcfSSatish Balay #include "petscsnes.h" 4*a7e14dcfSSatish Balay 5*a7e14dcfSSatish Balay 6*a7e14dcfSSatish Balay /* 7*a7e14dcfSSatish Balay For finited difference computations of the Hessian, we use PETSc's SNESComputeJacobianDefault 8*a7e14dcfSSatish Balay */ 9*a7e14dcfSSatish Balay 10*a7e14dcfSSatish Balay #undef __FUNCT__ 11*a7e14dcfSSatish Balay #define __FUNCT__ "Fsnes" 12*a7e14dcfSSatish Balay static PetscErrorCode Fsnes(SNES snes ,Vec X,Vec G,void*ctx){ 13*a7e14dcfSSatish Balay PetscErrorCode ierr; 14*a7e14dcfSSatish Balay TaoSolver tao = (TaoSolver)ctx; 15*a7e14dcfSSatish Balay PetscFunctionBegin; 16*a7e14dcfSSatish Balay PetscValidHeaderSpecific(ctx,TAOSOLVER_CLASSID,4); 17*a7e14dcfSSatish Balay ierr=TaoComputeGradient(tao,X,G); CHKERRQ(ierr); 18*a7e14dcfSSatish Balay PetscFunctionReturn(0); 19*a7e14dcfSSatish Balay } 20*a7e14dcfSSatish Balay 21*a7e14dcfSSatish Balay #undef __FUNCT__ 22*a7e14dcfSSatish Balay #define __FUNCT__ "TaoDefaultComputeGradient" 23*a7e14dcfSSatish Balay /*@C 24*a7e14dcfSSatish Balay TaoDefaultComputeGradient - computes the gradient using finite differences. 25*a7e14dcfSSatish Balay 26*a7e14dcfSSatish Balay Collective on TaoSolver 27*a7e14dcfSSatish Balay 28*a7e14dcfSSatish Balay Input Parameters: 29*a7e14dcfSSatish Balay + tao - the TaoSolver context 30*a7e14dcfSSatish Balay . X - compute gradient at this point 31*a7e14dcfSSatish Balay - dummy - not used 32*a7e14dcfSSatish Balay 33*a7e14dcfSSatish Balay Output Parameters: 34*a7e14dcfSSatish Balay . G - Gradient Vector 35*a7e14dcfSSatish Balay 36*a7e14dcfSSatish Balay Options Database Key: 37*a7e14dcfSSatish Balay + -tao_fd_gradient - Activates TaoDefaultComputeGradient() 38*a7e14dcfSSatish Balay - -tao_fd_delta <delta> - change in x used to calculate finite differences 39*a7e14dcfSSatish Balay 40*a7e14dcfSSatish Balay 41*a7e14dcfSSatish Balay 42*a7e14dcfSSatish Balay 43*a7e14dcfSSatish Balay Level: advanced 44*a7e14dcfSSatish Balay 45*a7e14dcfSSatish Balay Note: 46*a7e14dcfSSatish Balay This routine is slow and expensive, and is not currently optimized 47*a7e14dcfSSatish Balay to take advantage of sparsity in the problem. Although 48*a7e14dcfSSatish Balay TaoAppDefaultComputeGradient is not recommended for general use 49*a7e14dcfSSatish Balay in large-scale applications, It can be useful in checking the 50*a7e14dcfSSatish Balay correctness of a user-provided gradient. Use the tao method "tao_fd_test" 51*a7e14dcfSSatish Balay to get an indication of whether your gradient is correct. 52*a7e14dcfSSatish Balay 53*a7e14dcfSSatish Balay 54*a7e14dcfSSatish Balay Note: 55*a7e14dcfSSatish Balay This finite difference gradient evaluation can be set using the routine TaoSetGradientRoutine() or by using the command line option -tao_fd_gradient 56*a7e14dcfSSatish Balay 57*a7e14dcfSSatish Balay .seealso: TaoSetGradientRoutine() 58*a7e14dcfSSatish Balay 59*a7e14dcfSSatish Balay @*/ 60*a7e14dcfSSatish Balay PetscErrorCode TaoDefaultComputeGradient(TaoSolver tao,Vec X,Vec G,void *dummy) 61*a7e14dcfSSatish Balay { 62*a7e14dcfSSatish Balay PetscReal *g; 63*a7e14dcfSSatish Balay PetscReal f, f2; 64*a7e14dcfSSatish Balay PetscErrorCode ierr; 65*a7e14dcfSSatish Balay PetscInt low,high,N,i; 66*a7e14dcfSSatish Balay PetscBool flg; 67*a7e14dcfSSatish Balay PetscReal h=PETSC_SQRT_MACHINE_EPSILON; 68*a7e14dcfSSatish Balay PetscFunctionBegin; 69*a7e14dcfSSatish Balay ierr = TaoComputeObjective(tao, X,&f); CHKERRQ(ierr); 70*a7e14dcfSSatish Balay ierr = PetscOptionsGetReal(PETSC_NULL,"-tao_fd_delta",&h,&flg); CHKERRQ(ierr); 71*a7e14dcfSSatish Balay ierr = VecGetSize(X,&N); CHKERRQ(ierr); 72*a7e14dcfSSatish Balay ierr = VecGetOwnershipRange(X,&low,&high); CHKERRQ(ierr); 73*a7e14dcfSSatish Balay ierr = VecGetArray(G,&g); CHKERRQ(ierr); 74*a7e14dcfSSatish Balay for (i=0;i<N;i++) { 75*a7e14dcfSSatish Balay ierr = VecSetValue(X,i,h,ADD_VALUES); CHKERRQ(ierr); 76*a7e14dcfSSatish Balay ierr = VecAssemblyBegin(X); CHKERRQ(ierr); 77*a7e14dcfSSatish Balay ierr = VecAssemblyEnd(X); CHKERRQ(ierr); 78*a7e14dcfSSatish Balay 79*a7e14dcfSSatish Balay ierr = TaoComputeObjective(tao,X,&f2); CHKERRQ(ierr); 80*a7e14dcfSSatish Balay 81*a7e14dcfSSatish Balay ierr = VecSetValue(X,i,-h,ADD_VALUES); 82*a7e14dcfSSatish Balay ierr = VecAssemblyBegin(X); CHKERRQ(ierr); 83*a7e14dcfSSatish Balay ierr = VecAssemblyEnd(X); CHKERRQ(ierr); 84*a7e14dcfSSatish Balay 85*a7e14dcfSSatish Balay if (i>=low && i<high) { 86*a7e14dcfSSatish Balay g[i-low]=(f2-f)/h; 87*a7e14dcfSSatish Balay } 88*a7e14dcfSSatish Balay } 89*a7e14dcfSSatish Balay ierr = VecRestoreArray(G,&g); CHKERRQ(ierr); 90*a7e14dcfSSatish Balay PetscFunctionReturn(0); 91*a7e14dcfSSatish Balay } 92*a7e14dcfSSatish Balay 93*a7e14dcfSSatish Balay #undef __FUNCT__ 94*a7e14dcfSSatish Balay #define __FUNCT__ "TaoDefaultComputeHessian" 95*a7e14dcfSSatish Balay /*@C 96*a7e14dcfSSatish Balay TaoDefaultComputeHessian - Computes the Hessian using finite differences. 97*a7e14dcfSSatish Balay 98*a7e14dcfSSatish Balay Collective on TaoSolver 99*a7e14dcfSSatish Balay 100*a7e14dcfSSatish Balay Input Parameters: 101*a7e14dcfSSatish Balay + tao - the TaoSolver context 102*a7e14dcfSSatish Balay . V - compute Hessian at this point 103*a7e14dcfSSatish Balay - dummy - not used 104*a7e14dcfSSatish Balay 105*a7e14dcfSSatish Balay Output Parameters: 106*a7e14dcfSSatish Balay + H - Hessian matrix (not altered in this routine) 107*a7e14dcfSSatish Balay . B - newly computed Hessian matrix to use with preconditioner (generally the same as H) 108*a7e14dcfSSatish Balay - flag - flag indicating whether the matrix sparsity structure has changed 109*a7e14dcfSSatish Balay 110*a7e14dcfSSatish Balay Options Database Key: 111*a7e14dcfSSatish Balay + -tao_fd - Activates TaoDefaultComputeHessian() 112*a7e14dcfSSatish Balay - -tao_view_hessian - view the hessian after each evaluation using PETSC_VIEWER_STDOUT_WORLD 113*a7e14dcfSSatish Balay 114*a7e14dcfSSatish Balay Level: advanced 115*a7e14dcfSSatish Balay 116*a7e14dcfSSatish Balay Notes: 117*a7e14dcfSSatish Balay This routine is slow and expensive, and is not currently optimized 118*a7e14dcfSSatish Balay to take advantage of sparsity in the problem. Although 119*a7e14dcfSSatish Balay TaoDefaultComputeHessian() is not recommended for general use 120*a7e14dcfSSatish Balay in large-scale applications, It can be useful in checking the 121*a7e14dcfSSatish Balay correctness of a user-provided Hessian. 122*a7e14dcfSSatish Balay 123*a7e14dcfSSatish Balay 124*a7e14dcfSSatish Balay 125*a7e14dcfSSatish Balay .seealso: TaoSetHessianRoutine(), TaoDefaultComputeHessianColor(), SNESComputeJacobianDefault(), TaoSetGradientRoutine(), TaoDefaultComputeGradient() 126*a7e14dcfSSatish Balay 127*a7e14dcfSSatish Balay @*/ 128*a7e14dcfSSatish Balay PetscErrorCode TaoDefaultComputeHessian(TaoSolver tao,Vec V,Mat *H,Mat *B, 129*a7e14dcfSSatish Balay MatStructure *flag,void *dummy){ 130*a7e14dcfSSatish Balay PetscErrorCode ierr; 131*a7e14dcfSSatish Balay MPI_Comm comm; 132*a7e14dcfSSatish Balay Vec G; 133*a7e14dcfSSatish Balay SNES snes; 134*a7e14dcfSSatish Balay 135*a7e14dcfSSatish Balay PetscFunctionBegin; 136*a7e14dcfSSatish Balay PetscValidHeaderSpecific(V,VEC_CLASSID,2); 137*a7e14dcfSSatish Balay ierr = VecDuplicate(V,&G);CHKERRQ(ierr); 138*a7e14dcfSSatish Balay 139*a7e14dcfSSatish Balay ierr = PetscInfo(tao,"TAO Using finite differences w/o coloring to compute Hessian matrix\n"); CHKERRQ(ierr); 140*a7e14dcfSSatish Balay 141*a7e14dcfSSatish Balay ierr = TaoComputeGradient(tao,V,G); CHKERRQ(ierr); 142*a7e14dcfSSatish Balay 143*a7e14dcfSSatish Balay ierr = PetscObjectGetComm((PetscObject)(*H),&comm);CHKERRQ(ierr); 144*a7e14dcfSSatish Balay ierr = SNESCreate(comm,&snes);CHKERRQ(ierr); 145*a7e14dcfSSatish Balay 146*a7e14dcfSSatish Balay ierr = SNESSetFunction(snes,G,Fsnes,tao);CHKERRQ(ierr); 147*a7e14dcfSSatish Balay ierr = SNESComputeJacobianDefault(snes,V,H,B,flag,tao);CHKERRQ(ierr); 148*a7e14dcfSSatish Balay 149*a7e14dcfSSatish Balay ierr = SNESDestroy(&snes);CHKERRQ(ierr); 150*a7e14dcfSSatish Balay 151*a7e14dcfSSatish Balay ierr = VecDestroy(&G);CHKERRQ(ierr); 152*a7e14dcfSSatish Balay 153*a7e14dcfSSatish Balay PetscFunctionReturn(0); 154*a7e14dcfSSatish Balay } 155*a7e14dcfSSatish Balay 156*a7e14dcfSSatish Balay 157*a7e14dcfSSatish Balay 158*a7e14dcfSSatish Balay 159*a7e14dcfSSatish Balay #undef __FUNCT__ 160*a7e14dcfSSatish Balay #define __FUNCT__ "TaoDefaultComputeHessianColor" 161*a7e14dcfSSatish Balay /*@C 162*a7e14dcfSSatish Balay TaoDefaultComputeHessianColor - Computes the Hessian using colored finite differences. 163*a7e14dcfSSatish Balay 164*a7e14dcfSSatish Balay Collective on TaoSolver 165*a7e14dcfSSatish Balay 166*a7e14dcfSSatish Balay Input Parameters: 167*a7e14dcfSSatish Balay + tao - the TaoSolver context 168*a7e14dcfSSatish Balay . V - compute Hessian at this point 169*a7e14dcfSSatish Balay - ctx - the PetscColoring object (must be of type MatFDColoring) 170*a7e14dcfSSatish Balay 171*a7e14dcfSSatish Balay Output Parameters: 172*a7e14dcfSSatish Balay + H - Hessian matrix (not altered in this routine) 173*a7e14dcfSSatish Balay . B - newly computed Hessian matrix to use with preconditioner (generally the same as H) 174*a7e14dcfSSatish Balay - flag - flag indicating whether the matrix sparsity structure has changed 175*a7e14dcfSSatish Balay 176*a7e14dcfSSatish Balay Level: advanced 177*a7e14dcfSSatish Balay 178*a7e14dcfSSatish Balay 179*a7e14dcfSSatish Balay .seealso: TaoSetHessianRoutine(), TaoDefaultComputeHessian(),SNESComputeJacobianDefaultColor(), TaoSetGradientRoutine() 180*a7e14dcfSSatish Balay 181*a7e14dcfSSatish Balay @*/ 182*a7e14dcfSSatish Balay PetscErrorCode TaoDefaultComputeHessianColor(TaoSolver tao, Vec V, Mat *H,Mat *B,MatStructure *flag,void *ctx){ 183*a7e14dcfSSatish Balay PetscErrorCode ierr; 184*a7e14dcfSSatish Balay MatFDColoring coloring = (MatFDColoring)ctx; 185*a7e14dcfSSatish Balay 186*a7e14dcfSSatish Balay PetscFunctionBegin; 187*a7e14dcfSSatish Balay PetscValidHeaderSpecific(ctx,MAT_FDCOLORING_CLASSID,6); 188*a7e14dcfSSatish Balay 189*a7e14dcfSSatish Balay 190*a7e14dcfSSatish Balay 191*a7e14dcfSSatish Balay *flag = SAME_NONZERO_PATTERN; 192*a7e14dcfSSatish Balay 193*a7e14dcfSSatish Balay ierr=PetscInfo(tao,"TAO computing matrix using finite differences Hessian and coloring\n"); CHKERRQ(ierr); 194*a7e14dcfSSatish Balay ierr = MatFDColoringApply(*B,coloring,V,flag,ctx); CHKERRQ(ierr); 195*a7e14dcfSSatish Balay 196*a7e14dcfSSatish Balay if (*H != *B) { 197*a7e14dcfSSatish Balay ierr = MatAssemblyBegin(*H, MAT_FINAL_ASSEMBLY); CHKERRQ(ierr); 198*a7e14dcfSSatish Balay ierr = MatAssemblyEnd(*H, MAT_FINAL_ASSEMBLY); CHKERRQ(ierr); 199*a7e14dcfSSatish Balay } 200*a7e14dcfSSatish Balay PetscFunctionReturn(0); 201*a7e14dcfSSatish Balay } 202*a7e14dcfSSatish Balay 203*a7e14dcfSSatish Balay 204