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