xref: /petsc/src/tao/interface/taosolver_hj.c (revision 09baa8818311ab57ae2421c1358031095c8360c0)
1af0996ceSBarry Smith #include <petsc/private/taoimpl.h> /*I "petsctao.h" I*/
2a7e14dcfSSatish Balay 
3a7e14dcfSSatish Balay /*@C
4a7e14dcfSSatish Balay    TaoSetHessianRoutine - Sets the function to compute the Hessian as well as the location to store the matrix.
5a7e14dcfSSatish Balay 
6441846f8SBarry Smith    Logically collective on Tao
7a7e14dcfSSatish Balay 
8a7e14dcfSSatish Balay    Input Parameters:
9441846f8SBarry Smith +  tao  - the Tao context
10a7e14dcfSSatish Balay .  H    - Matrix used for the hessian
11a7e14dcfSSatish Balay .  Hpre - Matrix that will be used operated on by preconditioner, can be same as H
12f4c1ad5cSStefano Zampini .  func - Hessian evaluation routine
13a7e14dcfSSatish Balay -  ctx  - [optional] user-defined context for private data for the
146c23d075SBarry Smith          Hessian evaluation routine (may be NULL)
15a7e14dcfSSatish Balay 
16f4c1ad5cSStefano Zampini    Calling sequence of func:
17f4c1ad5cSStefano Zampini $    func(Tao tao,Vec x,Mat H,Mat Hpre,void *ctx);
18a7e14dcfSSatish Balay 
19441846f8SBarry Smith +  tao  - the Tao  context
20a7e14dcfSSatish Balay .  x    - input vector
21a7e14dcfSSatish Balay .  H    - Hessian matrix
22a7e14dcfSSatish Balay .  Hpre - preconditioner matrix, usually the same as H
23a7e14dcfSSatish Balay -  ctx  - [optional] user-defined Hessian context
24a7e14dcfSSatish Balay 
25a7e14dcfSSatish Balay    Level: beginner
26a7e14dcfSSatish Balay @*/
27ffad9901SBarry Smith PetscErrorCode TaoSetHessianRoutine(Tao tao, Mat H, Mat Hpre, PetscErrorCode (*func)(Tao, Vec, Mat, Mat, void*), void *ctx)
28a7e14dcfSSatish Balay {
29a7e14dcfSSatish Balay   PetscErrorCode ierr;
3045cf516eSBarry Smith 
31a7e14dcfSSatish Balay   PetscFunctionBegin;
32441846f8SBarry Smith   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
33a7e14dcfSSatish Balay   if (H) {
34a7e14dcfSSatish Balay     PetscValidHeaderSpecific(H,MAT_CLASSID,2);
35a7e14dcfSSatish Balay     PetscCheckSameComm(tao,1,H,2);
36a7e14dcfSSatish Balay   }
37a7e14dcfSSatish Balay   if (Hpre) {
38a7e14dcfSSatish Balay     PetscValidHeaderSpecific(Hpre,MAT_CLASSID,3);
39a7e14dcfSSatish Balay     PetscCheckSameComm(tao,1,Hpre,3);
40a7e14dcfSSatish Balay   }
41a7e14dcfSSatish Balay   if (ctx) {
42a7e14dcfSSatish Balay     tao->user_hessP = ctx;
43a7e14dcfSSatish Balay   }
44a7e14dcfSSatish Balay   if (func) {
45a7e14dcfSSatish Balay     tao->ops->computehessian = func;
46a7e14dcfSSatish Balay   }
47a7e14dcfSSatish Balay   if (H) {
48a7e14dcfSSatish Balay     ierr = PetscObjectReference((PetscObject)H);CHKERRQ(ierr);
4945cf516eSBarry Smith     ierr = MatDestroy(&tao->hessian);CHKERRQ(ierr);
50a7e14dcfSSatish Balay     tao->hessian = H;
51a7e14dcfSSatish Balay   }
52a7e14dcfSSatish Balay   if (Hpre) {
53a7e14dcfSSatish Balay     ierr = PetscObjectReference((PetscObject)Hpre);CHKERRQ(ierr);
5445cf516eSBarry Smith     ierr = MatDestroy(&tao->hessian_pre);CHKERRQ(ierr);
55a7e14dcfSSatish Balay     tao->hessian_pre = Hpre;
56a7e14dcfSSatish Balay   }
57a7e14dcfSSatish Balay   PetscFunctionReturn(0);
58a7e14dcfSSatish Balay }
59a7e14dcfSSatish Balay 
60*09baa881SHong Zhang PetscErrorCode TaoTestHessian(Tao tao)
61*09baa881SHong Zhang {
62*09baa881SHong Zhang   Mat              A,B,C,D,hessian;
63*09baa881SHong Zhang   Vec              x = tao->solution;
64*09baa881SHong Zhang   PetscErrorCode   ierr;
65*09baa881SHong Zhang   PetscReal        nrm,gnorm;
66*09baa881SHong Zhang   PetscReal        threshold = 1.e-5;
67*09baa881SHong Zhang   PetscInt         m,n,M,N;
68*09baa881SHong Zhang   PetscBool        complete_print = PETSC_FALSE,test = PETSC_FALSE,flg;
69*09baa881SHong Zhang   PetscViewer      viewer;
70*09baa881SHong Zhang   MPI_Comm         comm;
71*09baa881SHong Zhang   PetscInt         tabs;
72*09baa881SHong Zhang   static PetscBool directionsprinted = PETSC_FALSE;
73*09baa881SHong Zhang 
74*09baa881SHong Zhang   PetscFunctionBegin;
75*09baa881SHong Zhang   ierr = PetscObjectOptionsBegin((PetscObject)tao);CHKERRQ(ierr);
76*09baa881SHong Zhang   ierr = PetscOptionsName("-tao_test_hessian","Compare hand-coded and finite difference Hessians","None",&test);CHKERRQ(ierr);
77*09baa881SHong Zhang   ierr = PetscOptionsReal("-tao_test_hessian", "Threshold for element difference between hand-coded and finite difference being meaningful", "None", threshold, &threshold,NULL);CHKERRQ(ierr);
78*09baa881SHong Zhang   ierr = PetscOptionsBool("-tao_test_hessian_view","View difference between hand-coded and finite difference Hessians element entries","None",complete_print,&complete_print,NULL);CHKERRQ(ierr);
79*09baa881SHong Zhang   ierr = PetscOptionsEnd();CHKERRQ(ierr);
80*09baa881SHong Zhang   if (!test) PetscFunctionReturn(0);
81*09baa881SHong Zhang 
82*09baa881SHong Zhang   ierr = PetscObjectGetComm((PetscObject)tao,&comm);CHKERRQ(ierr);
83*09baa881SHong Zhang   ierr = PetscViewerASCIIGetStdout(comm,&viewer);CHKERRQ(ierr);
84*09baa881SHong Zhang   ierr = PetscViewerASCIIGetTab(viewer, &tabs);CHKERRQ(ierr);
85*09baa881SHong Zhang   ierr = PetscViewerASCIISetTab(viewer, ((PetscObject)tao)->tablevel);CHKERRQ(ierr);
86*09baa881SHong Zhang   ierr = PetscViewerASCIIPrintf(viewer,"  ---------- Testing Hessian -------------\n");CHKERRQ(ierr);
87*09baa881SHong Zhang   if (!complete_print && !directionsprinted) {
88*09baa881SHong Zhang     ierr = PetscViewerASCIIPrintf(viewer,"  Run with -tao_test_hessian_view and optionally -tao_test_hessian <threshold> to show difference\n");CHKERRQ(ierr);
89*09baa881SHong Zhang     ierr = PetscViewerASCIIPrintf(viewer,"    of hand-coded and finite difference Hessian entries greater than <threshold>.\n");CHKERRQ(ierr);
90*09baa881SHong Zhang   }
91*09baa881SHong Zhang   if (!directionsprinted) {
92*09baa881SHong Zhang     ierr = PetscViewerASCIIPrintf(viewer,"  Testing hand-coded Hessian, if (for double precision runs) ||J - Jfd||_F/||J||_F is\n");CHKERRQ(ierr);
93*09baa881SHong Zhang     ierr = PetscViewerASCIIPrintf(viewer,"    O(1.e-8), the hand-coded Hessian is probably correct.\n");CHKERRQ(ierr);
94*09baa881SHong Zhang     directionsprinted = PETSC_TRUE;
95*09baa881SHong Zhang   }
96*09baa881SHong Zhang 
97*09baa881SHong Zhang   ierr = PetscObjectTypeCompare((PetscObject)tao->hessian,MATMFFD,&flg);CHKERRQ(ierr);
98*09baa881SHong Zhang   if (!flg) hessian = tao->hessian;
99*09baa881SHong Zhang   else hessian = tao->hessian_pre;
100*09baa881SHong Zhang 
101*09baa881SHong Zhang   while (hessian) {
102*09baa881SHong Zhang     ierr = PetscObjectTypeCompareAny((PetscObject)hessian,&flg,MATSEQAIJ,MATMPIAIJ,MATSEQDENSE,MATMPIDENSE,MATSEQBAIJ,MATMPIBAIJ,MATSEQSBAIJ,MATMPIBAIJ,"");CHKERRQ(ierr);
103*09baa881SHong Zhang     if (flg) {
104*09baa881SHong Zhang       A    = hessian;
105*09baa881SHong Zhang       ierr = PetscObjectReference((PetscObject)A);CHKERRQ(ierr);
106*09baa881SHong Zhang     } else {
107*09baa881SHong Zhang       ierr = MatComputeExplicitOperator(hessian,&A);CHKERRQ(ierr);
108*09baa881SHong Zhang     }
109*09baa881SHong Zhang 
110*09baa881SHong Zhang     ierr = MatCreate(PetscObjectComm((PetscObject)A),&B);CHKERRQ(ierr);
111*09baa881SHong Zhang     ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
112*09baa881SHong Zhang     ierr = MatGetLocalSize(A,&m,&n);CHKERRQ(ierr);
113*09baa881SHong Zhang     ierr = MatSetSizes(B,m,n,M,N);CHKERRQ(ierr);
114*09baa881SHong Zhang     ierr = MatSetType(B,((PetscObject)A)->type_name);CHKERRQ(ierr);
115*09baa881SHong Zhang     ierr = MatSetUp(B);CHKERRQ(ierr);
116*09baa881SHong Zhang     ierr = MatSetOption(B,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_FALSE);CHKERRQ(ierr);
117*09baa881SHong Zhang 
118*09baa881SHong Zhang     ierr = TaoDefaultComputeHessian(tao,x,B,B,NULL);CHKERRQ(ierr);
119*09baa881SHong Zhang 
120*09baa881SHong Zhang     ierr = MatDuplicate(B,MAT_COPY_VALUES,&D);CHKERRQ(ierr);
121*09baa881SHong Zhang     ierr = MatAYPX(D,-1.0,A,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr);
122*09baa881SHong Zhang     ierr = MatNorm(D,NORM_FROBENIUS,&nrm);CHKERRQ(ierr);
123*09baa881SHong Zhang     ierr = MatNorm(A,NORM_FROBENIUS,&gnorm);CHKERRQ(ierr);
124*09baa881SHong Zhang     ierr = MatDestroy(&D);CHKERRQ(ierr);
125*09baa881SHong Zhang     if (!gnorm) gnorm = 1; /* just in case */
126*09baa881SHong Zhang     ierr = PetscViewerASCIIPrintf(viewer,"  ||H - Hfd||_F/||H||_F = %g, ||H - Hfd||_F = %g\n",(double)(nrm/gnorm),(double)nrm);CHKERRQ(ierr);
127*09baa881SHong Zhang 
128*09baa881SHong Zhang     if (complete_print) {
129*09baa881SHong Zhang       ierr = PetscViewerASCIIPrintf(viewer,"  Hand-coded Hessian ----------\n");CHKERRQ(ierr);
130*09baa881SHong Zhang       ierr = MatView(hessian,viewer);CHKERRQ(ierr);
131*09baa881SHong Zhang       ierr = PetscViewerASCIIPrintf(viewer,"  Finite difference Hessian ----------\n");CHKERRQ(ierr);
132*09baa881SHong Zhang       ierr = MatView(B,viewer);CHKERRQ(ierr);
133*09baa881SHong Zhang     }
134*09baa881SHong Zhang 
135*09baa881SHong Zhang     if (complete_print) {
136*09baa881SHong Zhang       PetscInt          Istart, Iend, *ccols, bncols, cncols, j, row;
137*09baa881SHong Zhang       PetscScalar       *cvals;
138*09baa881SHong Zhang       const PetscInt    *bcols;
139*09baa881SHong Zhang       const PetscScalar *bvals;
140*09baa881SHong Zhang 
141*09baa881SHong Zhang       ierr = MatAYPX(B,-1.0,A,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr);
142*09baa881SHong Zhang       ierr = MatCreate(PetscObjectComm((PetscObject)A),&C);CHKERRQ(ierr);
143*09baa881SHong Zhang       ierr = MatSetSizes(C,m,n,M,N);CHKERRQ(ierr);
144*09baa881SHong Zhang       ierr = MatSetType(C,((PetscObject)A)->type_name);CHKERRQ(ierr);
145*09baa881SHong Zhang       ierr = MatSetUp(C);CHKERRQ(ierr);
146*09baa881SHong Zhang       ierr = MatSetOption(C,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_FALSE);CHKERRQ(ierr);
147*09baa881SHong Zhang       ierr = MatGetOwnershipRange(B,&Istart,&Iend);CHKERRQ(ierr);
148*09baa881SHong Zhang 
149*09baa881SHong Zhang       for (row = Istart; row < Iend; row++) {
150*09baa881SHong Zhang         ierr = MatGetRow(B,row,&bncols,&bcols,&bvals);CHKERRQ(ierr);
151*09baa881SHong Zhang         ierr = PetscMalloc2(bncols,&ccols,bncols,&cvals);CHKERRQ(ierr);
152*09baa881SHong Zhang         for (j = 0, cncols = 0; j < bncols; j++) {
153*09baa881SHong Zhang           if (PetscAbsScalar(bvals[j]) > threshold) {
154*09baa881SHong Zhang             ccols[cncols] = bcols[j];
155*09baa881SHong Zhang             cvals[cncols] = bvals[j];
156*09baa881SHong Zhang             cncols += 1;
157*09baa881SHong Zhang           }
158*09baa881SHong Zhang         }
159*09baa881SHong Zhang         if (cncols) {
160*09baa881SHong Zhang           ierr = MatSetValues(C,1,&row,cncols,ccols,cvals,INSERT_VALUES);CHKERRQ(ierr);
161*09baa881SHong Zhang         }
162*09baa881SHong Zhang         ierr = MatRestoreRow(B,row,&bncols,&bcols,&bvals);CHKERRQ(ierr);
163*09baa881SHong Zhang         ierr = PetscFree2(ccols,cvals);CHKERRQ(ierr);
164*09baa881SHong Zhang       }
165*09baa881SHong Zhang       ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
166*09baa881SHong Zhang       ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
167*09baa881SHong Zhang       ierr = PetscViewerASCIIPrintf(viewer,"  Finite-difference minus hand-coded Hessian with tolerance %g ----------\n",(double)threshold);CHKERRQ(ierr);
168*09baa881SHong Zhang       ierr = MatView(C,viewer);CHKERRQ(ierr);
169*09baa881SHong Zhang       ierr = MatDestroy(&C);CHKERRQ(ierr);
170*09baa881SHong Zhang     }
171*09baa881SHong Zhang     ierr = MatDestroy(&A);CHKERRQ(ierr);
172*09baa881SHong Zhang     ierr = MatDestroy(&B);CHKERRQ(ierr);
173*09baa881SHong Zhang 
174*09baa881SHong Zhang     if (hessian != tao->hessian_pre) {
175*09baa881SHong Zhang       hessian = tao->hessian_pre;
176*09baa881SHong Zhang       ierr = PetscViewerASCIIPrintf(viewer,"  ---------- Testing Hessian for preconditioner -------------\n");CHKERRQ(ierr);
177*09baa881SHong Zhang     } else hessian = NULL;
178*09baa881SHong Zhang   }
179*09baa881SHong Zhang   ierr = PetscViewerASCIISetTab(viewer,tabs);CHKERRQ(ierr);
180*09baa881SHong Zhang   PetscFunctionReturn(0);
181*09baa881SHong Zhang }
182*09baa881SHong Zhang 
183a7e14dcfSSatish Balay /*@C
184a7e14dcfSSatish Balay    TaoComputeHessian - Computes the Hessian matrix that has been
185a7e14dcfSSatish Balay    set with TaoSetHessianRoutine().
186a7e14dcfSSatish Balay 
187441846f8SBarry Smith    Collective on Tao
188a7e14dcfSSatish Balay 
189a7e14dcfSSatish Balay    Input Parameters:
190f4c1ad5cSStefano Zampini +  tao - the Tao solver context
191f4c1ad5cSStefano Zampini -  X   - input vector
192a7e14dcfSSatish Balay 
193a7e14dcfSSatish Balay    Output Parameters:
194a7e14dcfSSatish Balay +  H    - Hessian matrix
195aa6c7ce3SBarry Smith -  Hpre - Preconditioning matrix
196a7e14dcfSSatish Balay 
197*09baa881SHong Zhang    Options Database Keys:
198*09baa881SHong Zhang +     -tao_test_hessian - compare the user provided Hessian with one compute via finite differences to check for errors
199*09baa881SHong Zhang .     -tao_test_hessian <numerical value>  - display entries in the difference between the user provided Hessian and finite difference Hessian that are greater than a certain value to help users detect errors
200*09baa881SHong Zhang -     -tao_test_hessian_display - display the user provided Hessian, the finite difference Hessian and the difference between them to help users detect the location of errors in the user provided Hessian
201*09baa881SHong Zhang 
202a7e14dcfSSatish Balay    Notes:
203a7e14dcfSSatish Balay    Most users should not need to explicitly call this routine, as it
204a7e14dcfSSatish Balay    is used internally within the minimization solvers.
205a7e14dcfSSatish Balay 
206a7e14dcfSSatish Balay    TaoComputeHessian() is typically used within minimization
207a7e14dcfSSatish Balay    implementations, so most users would not generally call this routine
208a7e14dcfSSatish Balay    themselves.
209a7e14dcfSSatish Balay 
210*09baa881SHong Zhang    Developer Notes:
211*09baa881SHong Zhang    The Hessian test mechanism follows SNESTestJacobian().
212*09baa881SHong Zhang 
213a7e14dcfSSatish Balay    Level: developer
214a7e14dcfSSatish Balay 
215f4c1ad5cSStefano Zampini .seealso: TaoComputeObjective(), TaoComputeObjectiveAndGradient(), TaoSetHessianRoutine()
216a7e14dcfSSatish Balay @*/
217ffad9901SBarry Smith PetscErrorCode TaoComputeHessian(Tao tao, Vec X, Mat H, Mat Hpre)
218a7e14dcfSSatish Balay {
219a7e14dcfSSatish Balay   PetscErrorCode ierr;
22087f595a5SBarry Smith 
221a7e14dcfSSatish Balay   PetscFunctionBegin;
222441846f8SBarry Smith   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
223a7e14dcfSSatish Balay   PetscValidHeaderSpecific(X, VEC_CLASSID,2);
224a7e14dcfSSatish Balay   PetscCheckSameComm(tao,1,X,2);
225f4c1ad5cSStefano Zampini   if (!tao->ops->computehessian) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Must call TaoSetHessianRoutine() first");
226a7e14dcfSSatish Balay   ++tao->nhess;
227f4c1ad5cSStefano Zampini   ierr = VecLockPush(X);CHKERRQ(ierr);
22894ab13aaSBarry Smith   ierr = PetscLogEventBegin(Tao_HessianEval,tao,X,H,Hpre);CHKERRQ(ierr);
229441846f8SBarry Smith   PetscStackPush("Tao user Hessian function");
230ffad9901SBarry Smith   ierr = (*tao->ops->computehessian)(tao,X,H,Hpre,tao->user_hessP);CHKERRQ(ierr);
231a7e14dcfSSatish Balay   PetscStackPop;
23294ab13aaSBarry Smith   ierr = PetscLogEventEnd(Tao_HessianEval,tao,X,H,Hpre);CHKERRQ(ierr);
233f4c1ad5cSStefano Zampini   ierr = VecLockPop(X);CHKERRQ(ierr);
234*09baa881SHong Zhang 
235*09baa881SHong Zhang   ierr = TaoTestHessian(tao);CHKERRQ(ierr);
236a7e14dcfSSatish Balay   PetscFunctionReturn(0);
237a7e14dcfSSatish Balay }
238a7e14dcfSSatish Balay 
239a7e14dcfSSatish Balay /*@C
240a7e14dcfSSatish Balay    TaoComputeJacobian - Computes the Jacobian matrix that has been
241a7e14dcfSSatish Balay    set with TaoSetJacobianRoutine().
242a7e14dcfSSatish Balay 
243441846f8SBarry Smith    Collective on Tao
244a7e14dcfSSatish Balay 
245a7e14dcfSSatish Balay    Input Parameters:
246f4c1ad5cSStefano Zampini +  tao - the Tao solver context
247f4c1ad5cSStefano Zampini -  X   - input vector
248a7e14dcfSSatish Balay 
249a7e14dcfSSatish Balay    Output Parameters:
250f4c1ad5cSStefano Zampini +  J    - Jacobian matrix
251f4c1ad5cSStefano Zampini -  Jpre - Preconditioning matrix
252a7e14dcfSSatish Balay 
253a7e14dcfSSatish Balay    Notes:
254a7e14dcfSSatish Balay    Most users should not need to explicitly call this routine, as it
255a7e14dcfSSatish Balay    is used internally within the minimization solvers.
256a7e14dcfSSatish Balay 
257a7e14dcfSSatish Balay    TaoComputeJacobian() is typically used within minimization
258a7e14dcfSSatish Balay    implementations, so most users would not generally call this routine
259a7e14dcfSSatish Balay    themselves.
260a7e14dcfSSatish Balay 
261a7e14dcfSSatish Balay    Level: developer
262a7e14dcfSSatish Balay 
263f4c1ad5cSStefano Zampini .seealso: TaoComputeObjective(), TaoComputeObjectiveAndGradient(), TaoSetJacobianRoutine()
264a7e14dcfSSatish Balay @*/
265ffad9901SBarry Smith PetscErrorCode TaoComputeJacobian(Tao tao, Vec X, Mat J, Mat Jpre)
266a7e14dcfSSatish Balay {
267a7e14dcfSSatish Balay   PetscErrorCode ierr;
26887f595a5SBarry Smith 
269a7e14dcfSSatish Balay   PetscFunctionBegin;
270441846f8SBarry Smith   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
271a7e14dcfSSatish Balay   PetscValidHeaderSpecific(X, VEC_CLASSID,2);
272a7e14dcfSSatish Balay   PetscCheckSameComm(tao,1,X,2);
27387f595a5SBarry Smith   if (!tao->ops->computejacobian) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Must call TaoSetJacobian() first");
274a7e14dcfSSatish Balay   ++tao->njac;
275f4c1ad5cSStefano Zampini   ierr = VecLockPush(X);CHKERRQ(ierr);
27694ab13aaSBarry Smith   ierr = PetscLogEventBegin(Tao_JacobianEval,tao,X,J,Jpre);CHKERRQ(ierr);
277441846f8SBarry Smith   PetscStackPush("Tao user Jacobian function");
278ffad9901SBarry Smith   ierr = (*tao->ops->computejacobian)(tao,X,J,Jpre,tao->user_jacP);CHKERRQ(ierr);
279a7e14dcfSSatish Balay   PetscStackPop;
28094ab13aaSBarry Smith   ierr = PetscLogEventEnd(Tao_JacobianEval,tao,X,J,Jpre);CHKERRQ(ierr);
281f4c1ad5cSStefano Zampini   ierr = VecLockPop(X);CHKERRQ(ierr);
282a7e14dcfSSatish Balay   PetscFunctionReturn(0);
283a7e14dcfSSatish Balay }
284a7e14dcfSSatish Balay 
285a7e14dcfSSatish Balay /*@C
286a7e14dcfSSatish Balay    TaoComputeJacobianState - Computes the Jacobian matrix that has been
287a7e14dcfSSatish Balay    set with TaoSetJacobianStateRoutine().
288a7e14dcfSSatish Balay 
289441846f8SBarry Smith    Collective on Tao
290a7e14dcfSSatish Balay 
291a7e14dcfSSatish Balay    Input Parameters:
292f4c1ad5cSStefano Zampini +  tao - the Tao solver context
293f4c1ad5cSStefano Zampini -  X   - input vector
294a7e14dcfSSatish Balay 
295a7e14dcfSSatish Balay    Output Parameters:
296f4c1ad5cSStefano Zampini +  Jpre - Jacobian matrix
297f4c1ad5cSStefano Zampini -  Jinv - Preconditioning matrix
298a7e14dcfSSatish Balay 
299a7e14dcfSSatish Balay    Notes:
300a7e14dcfSSatish Balay    Most users should not need to explicitly call this routine, as it
301a7e14dcfSSatish Balay    is used internally within the minimization solvers.
302a7e14dcfSSatish Balay 
303a7e14dcfSSatish Balay    TaoComputeJacobianState() is typically used within minimization
304a7e14dcfSSatish Balay    implementations, so most users would not generally call this routine
305a7e14dcfSSatish Balay    themselves.
306a7e14dcfSSatish Balay 
307a7e14dcfSSatish Balay    Level: developer
308a7e14dcfSSatish Balay 
309a7e14dcfSSatish Balay .seealso: TaoComputeObjective(), TaoComputeObjectiveAndGradient(), TaoSetJacobianStateRoutine(), TaoComputeJacobianDesign(), TaoSetStateDesignIS()
310a7e14dcfSSatish Balay @*/
311ffad9901SBarry Smith PetscErrorCode TaoComputeJacobianState(Tao tao, Vec X, Mat J, Mat Jpre, Mat Jinv)
312a7e14dcfSSatish Balay {
313a7e14dcfSSatish Balay   PetscErrorCode ierr;
31445cf516eSBarry Smith 
315a7e14dcfSSatish Balay   PetscFunctionBegin;
316441846f8SBarry Smith   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
317a7e14dcfSSatish Balay   PetscValidHeaderSpecific(X, VEC_CLASSID,2);
318a7e14dcfSSatish Balay   PetscCheckSameComm(tao,1,X,2);
31987f595a5SBarry Smith   if (!tao->ops->computejacobianstate) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Must call TaoSetJacobianState() first");
320a7e14dcfSSatish Balay   ++tao->njac_state;
321f4c1ad5cSStefano Zampini   ierr = VecLockPush(X);CHKERRQ(ierr);
32294ab13aaSBarry Smith   ierr = PetscLogEventBegin(Tao_JacobianEval,tao,X,J,Jpre);CHKERRQ(ierr);
323441846f8SBarry Smith   PetscStackPush("Tao user Jacobian(state) function");
324ffad9901SBarry Smith   ierr = (*tao->ops->computejacobianstate)(tao,X,J,Jpre,Jinv,tao->user_jac_stateP);CHKERRQ(ierr);
325a7e14dcfSSatish Balay   PetscStackPop;
32694ab13aaSBarry Smith   ierr = PetscLogEventEnd(Tao_JacobianEval,tao,X,J,Jpre);CHKERRQ(ierr);
327f4c1ad5cSStefano Zampini   ierr = VecLockPop(X);CHKERRQ(ierr);
328a7e14dcfSSatish Balay   PetscFunctionReturn(0);
329a7e14dcfSSatish Balay }
330a7e14dcfSSatish Balay 
331a7e14dcfSSatish Balay /*@C
332a7e14dcfSSatish Balay    TaoComputeJacobianDesign - Computes the Jacobian matrix that has been
333a7e14dcfSSatish Balay    set with TaoSetJacobianDesignRoutine().
334a7e14dcfSSatish Balay 
335441846f8SBarry Smith    Collective on Tao
336a7e14dcfSSatish Balay 
337a7e14dcfSSatish Balay    Input Parameters:
338f4c1ad5cSStefano Zampini +  tao - the Tao solver context
339f4c1ad5cSStefano Zampini -  X   - input vector
340a7e14dcfSSatish Balay 
341a7e14dcfSSatish Balay    Output Parameters:
342f4c1ad5cSStefano Zampini .  J - Jacobian matrix
343a7e14dcfSSatish Balay 
344a7e14dcfSSatish Balay    Notes:
345a7e14dcfSSatish Balay    Most users should not need to explicitly call this routine, as it
346a7e14dcfSSatish Balay    is used internally within the minimization solvers.
347a7e14dcfSSatish Balay 
348a7e14dcfSSatish Balay    TaoComputeJacobianDesign() is typically used within minimization
349a7e14dcfSSatish Balay    implementations, so most users would not generally call this routine
350a7e14dcfSSatish Balay    themselves.
351a7e14dcfSSatish Balay 
352a7e14dcfSSatish Balay    Level: developer
353a7e14dcfSSatish Balay 
354a7e14dcfSSatish Balay .seealso:  TaoComputeObjective(), TaoComputeObjectiveAndGradient(), TaoSetJacobianDesignRoutine(), TaoComputeJacobianDesign(), TaoSetStateDesignIS()
355a7e14dcfSSatish Balay @*/
35694ab13aaSBarry Smith PetscErrorCode TaoComputeJacobianDesign(Tao tao, Vec X, Mat J)
357a7e14dcfSSatish Balay {
358a7e14dcfSSatish Balay   PetscErrorCode ierr;
35987f595a5SBarry Smith 
360a7e14dcfSSatish Balay   PetscFunctionBegin;
361441846f8SBarry Smith   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
362a7e14dcfSSatish Balay   PetscValidHeaderSpecific(X, VEC_CLASSID,2);
363a7e14dcfSSatish Balay   PetscCheckSameComm(tao,1,X,2);
36487f595a5SBarry Smith   if (!tao->ops->computejacobiandesign) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Must call TaoSetJacobianDesign() first");
365a7e14dcfSSatish Balay   ++tao->njac_design;
366f4c1ad5cSStefano Zampini   ierr = VecLockPush(X);CHKERRQ(ierr);
36794ab13aaSBarry Smith   ierr = PetscLogEventBegin(Tao_JacobianEval,tao,X,J,NULL);CHKERRQ(ierr);
368441846f8SBarry Smith   PetscStackPush("Tao user Jacobian(design) function");
369a7e14dcfSSatish Balay   ierr = (*tao->ops->computejacobiandesign)(tao,X,J,tao->user_jac_designP);CHKERRQ(ierr);
370a7e14dcfSSatish Balay   PetscStackPop;
37194ab13aaSBarry Smith   ierr = PetscLogEventEnd(Tao_JacobianEval,tao,X,J,NULL);CHKERRQ(ierr);
372f4c1ad5cSStefano Zampini   ierr = VecLockPop(X);CHKERRQ(ierr);
373a7e14dcfSSatish Balay   PetscFunctionReturn(0);
374a7e14dcfSSatish Balay }
375a7e14dcfSSatish Balay 
376a7e14dcfSSatish Balay /*@C
377a7e14dcfSSatish Balay    TaoSetJacobianRoutine - Sets the function to compute the Jacobian as well as the location to store the matrix.
378a7e14dcfSSatish Balay 
379441846f8SBarry Smith    Logically collective on Tao
380a7e14dcfSSatish Balay 
381a7e14dcfSSatish Balay    Input Parameters:
382441846f8SBarry Smith +  tao  - the Tao context
383a7e14dcfSSatish Balay .  J    - Matrix used for the jacobian
384a7e14dcfSSatish Balay .  Jpre - Matrix that will be used operated on by preconditioner, can be same as J
385f4c1ad5cSStefano Zampini .  func - Jacobian evaluation routine
386a7e14dcfSSatish Balay -  ctx  - [optional] user-defined context for private data for the
3876c23d075SBarry Smith           Jacobian evaluation routine (may be NULL)
388a7e14dcfSSatish Balay 
389f4c1ad5cSStefano Zampini    Calling sequence of func:
390f4c1ad5cSStefano Zampini $    func(Tao tao,Vec x,Mat J,Mat Jpre,void *ctx);
391a7e14dcfSSatish Balay 
392441846f8SBarry Smith +  tao  - the Tao  context
393a7e14dcfSSatish Balay .  x    - input vector
394a7e14dcfSSatish Balay .  J    - Jacobian matrix
395f4c1ad5cSStefano Zampini .  Jpre - preconditioning matrix, usually the same as J
396a7e14dcfSSatish Balay -  ctx  - [optional] user-defined Jacobian context
397a7e14dcfSSatish Balay 
398a7e14dcfSSatish Balay    Level: intermediate
399a7e14dcfSSatish Balay @*/
400ffad9901SBarry Smith PetscErrorCode TaoSetJacobianRoutine(Tao tao, Mat J, Mat Jpre, PetscErrorCode (*func)(Tao, Vec, Mat, Mat, void*), void *ctx)
401a7e14dcfSSatish Balay {
402a7e14dcfSSatish Balay   PetscErrorCode ierr;
403f4c1ad5cSStefano Zampini 
404a7e14dcfSSatish Balay   PetscFunctionBegin;
405441846f8SBarry Smith   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
406a7e14dcfSSatish Balay   if (J) {
407a7e14dcfSSatish Balay     PetscValidHeaderSpecific(J,MAT_CLASSID,2);
408a7e14dcfSSatish Balay     PetscCheckSameComm(tao,1,J,2);
409a7e14dcfSSatish Balay   }
410a7e14dcfSSatish Balay   if (Jpre) {
411a7e14dcfSSatish Balay     PetscValidHeaderSpecific(Jpre,MAT_CLASSID,3);
412a7e14dcfSSatish Balay     PetscCheckSameComm(tao,1,Jpre,3);
413a7e14dcfSSatish Balay   }
414a7e14dcfSSatish Balay   if (ctx) {
415a7e14dcfSSatish Balay     tao->user_jacP = ctx;
416a7e14dcfSSatish Balay   }
417a7e14dcfSSatish Balay   if (func) {
418a7e14dcfSSatish Balay     tao->ops->computejacobian = func;
419a7e14dcfSSatish Balay   }
420a7e14dcfSSatish Balay   if (J) {
421a7e14dcfSSatish Balay     ierr = PetscObjectReference((PetscObject)J);CHKERRQ(ierr);
42245cf516eSBarry Smith     ierr = MatDestroy(&tao->jacobian);CHKERRQ(ierr);
423a7e14dcfSSatish Balay     tao->jacobian = J;
424a7e14dcfSSatish Balay   }
425a7e14dcfSSatish Balay   if (Jpre) {
426a7e14dcfSSatish Balay     ierr = PetscObjectReference((PetscObject)Jpre);CHKERRQ(ierr);
42745cf516eSBarry Smith     ierr = MatDestroy(&tao->jacobian_pre);CHKERRQ(ierr);
428a7e14dcfSSatish Balay     tao->jacobian_pre=Jpre;
429a7e14dcfSSatish Balay   }
430a7e14dcfSSatish Balay   PetscFunctionReturn(0);
431a7e14dcfSSatish Balay }
432a7e14dcfSSatish Balay 
433a7e14dcfSSatish Balay /*@C
434a7e14dcfSSatish Balay    TaoSetJacobianStateRoutine - Sets the function to compute the Jacobian
435a7e14dcfSSatish Balay    (and its inverse) of the constraint function with respect to the state variables.
436a7e14dcfSSatish Balay    Used only for pde-constrained optimization.
437a7e14dcfSSatish Balay 
438441846f8SBarry Smith    Logically collective on Tao
439a7e14dcfSSatish Balay 
440a7e14dcfSSatish Balay    Input Parameters:
441441846f8SBarry Smith +  tao  - the Tao context
442a7e14dcfSSatish Balay .  J    - Matrix used for the jacobian
4436c23d075SBarry Smith .  Jpre - Matrix that will be used operated on by PETSc preconditioner, can be same as J.  Only used if Jinv is NULL
4446c23d075SBarry Smith .  Jinv - [optional] Matrix used to apply the inverse of the state jacobian. Use NULL to default to PETSc KSP solvers to apply the inverse.
445f4c1ad5cSStefano Zampini .  func - Jacobian evaluation routine
446a7e14dcfSSatish Balay -  ctx  - [optional] user-defined context for private data for the
4476c23d075SBarry Smith           Jacobian evaluation routine (may be NULL)
448a7e14dcfSSatish Balay 
449f4c1ad5cSStefano Zampini    Calling sequence of func:
450f4c1ad5cSStefano Zampini $    func(Tao tao,Vec x,Mat J,Mat Jpre,Mat Jinv,void *ctx);
451a7e14dcfSSatish Balay 
452441846f8SBarry Smith +  tao  - the Tao  context
453a7e14dcfSSatish Balay .  x    - input vector
454a7e14dcfSSatish Balay .  J    - Jacobian matrix
455a7e14dcfSSatish Balay .  Jpre - preconditioner matrix, usually the same as J
456a7e14dcfSSatish Balay .  Jinv - inverse of J
457a7e14dcfSSatish Balay -  ctx  - [optional] user-defined Jacobian context
458a7e14dcfSSatish Balay 
459a7e14dcfSSatish Balay    Level: intermediate
460f4c1ad5cSStefano Zampini .seealso: TaoComputeJacobianState(), TaoSetJacobianDesignRoutine(), TaoSetStateDesignIS()
461a7e14dcfSSatish Balay @*/
462ffad9901SBarry Smith PetscErrorCode TaoSetJacobianStateRoutine(Tao tao, Mat J, Mat Jpre, Mat Jinv, PetscErrorCode (*func)(Tao, Vec, Mat, Mat, Mat, void*), void *ctx)
463a7e14dcfSSatish Balay {
464a7e14dcfSSatish Balay   PetscErrorCode ierr;
465f4c1ad5cSStefano Zampini 
466a7e14dcfSSatish Balay   PetscFunctionBegin;
467441846f8SBarry Smith   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
468a7e14dcfSSatish Balay   if (J) {
469a7e14dcfSSatish Balay     PetscValidHeaderSpecific(J,MAT_CLASSID,2);
470a7e14dcfSSatish Balay     PetscCheckSameComm(tao,1,J,2);
471a7e14dcfSSatish Balay   }
472a7e14dcfSSatish Balay   if (Jpre) {
473a7e14dcfSSatish Balay     PetscValidHeaderSpecific(Jpre,MAT_CLASSID,3);
474a7e14dcfSSatish Balay     PetscCheckSameComm(tao,1,Jpre,3);
475a7e14dcfSSatish Balay   }
476a7e14dcfSSatish Balay   if (Jinv) {
477a7e14dcfSSatish Balay     PetscValidHeaderSpecific(Jinv,MAT_CLASSID,4);
478a7e14dcfSSatish Balay     PetscCheckSameComm(tao,1,Jinv,4);
479a7e14dcfSSatish Balay   }
480a7e14dcfSSatish Balay   if (ctx) {
481a7e14dcfSSatish Balay     tao->user_jac_stateP = ctx;
482a7e14dcfSSatish Balay   }
483a7e14dcfSSatish Balay   if (func) {
484a7e14dcfSSatish Balay     tao->ops->computejacobianstate = func;
485a7e14dcfSSatish Balay   }
486a7e14dcfSSatish Balay   if (J) {
487a7e14dcfSSatish Balay     ierr = PetscObjectReference((PetscObject)J);CHKERRQ(ierr);
48845cf516eSBarry Smith     ierr = MatDestroy(&tao->jacobian_state);CHKERRQ(ierr);
489a7e14dcfSSatish Balay     tao->jacobian_state = J;
490a7e14dcfSSatish Balay   }
491a7e14dcfSSatish Balay   if (Jpre) {
492a7e14dcfSSatish Balay     ierr = PetscObjectReference((PetscObject)Jpre);CHKERRQ(ierr);
49345cf516eSBarry Smith     ierr = MatDestroy(&tao->jacobian_state_pre);CHKERRQ(ierr);
494a7e14dcfSSatish Balay     tao->jacobian_state_pre=Jpre;
495a7e14dcfSSatish Balay   }
496a7e14dcfSSatish Balay   if (Jinv) {
497a7e14dcfSSatish Balay     ierr = PetscObjectReference((PetscObject)Jinv);CHKERRQ(ierr);
49845cf516eSBarry Smith     ierr = MatDestroy(&tao->jacobian_state_inv);CHKERRQ(ierr);
499a7e14dcfSSatish Balay     tao->jacobian_state_inv=Jinv;
500a7e14dcfSSatish Balay   }
501a7e14dcfSSatish Balay   PetscFunctionReturn(0);
502a7e14dcfSSatish Balay }
503a7e14dcfSSatish Balay 
504a7e14dcfSSatish Balay /*@C
505a7e14dcfSSatish Balay    TaoSetJacobianDesignRoutine - Sets the function to compute the Jacobian of
506a7e14dcfSSatish Balay    the constraint function with respect to the design variables.  Used only for
507a7e14dcfSSatish Balay    pde-constrained optimization.
508a7e14dcfSSatish Balay 
509441846f8SBarry Smith    Logically collective on Tao
510a7e14dcfSSatish Balay 
511a7e14dcfSSatish Balay    Input Parameters:
512441846f8SBarry Smith +  tao  - the Tao context
513a7e14dcfSSatish Balay .  J    - Matrix used for the jacobian
514f4c1ad5cSStefano Zampini .  func - Jacobian evaluation routine
515a7e14dcfSSatish Balay -  ctx  - [optional] user-defined context for private data for the
5166c23d075SBarry Smith           Jacobian evaluation routine (may be NULL)
517a7e14dcfSSatish Balay 
518f4c1ad5cSStefano Zampini    Calling sequence of func:
519f4c1ad5cSStefano Zampini $    func(Tao tao,Vec x,Mat J,void *ctx);
520a7e14dcfSSatish Balay 
521441846f8SBarry Smith +  tao - the Tao  context
522a7e14dcfSSatish Balay .  x   - input vector
523a7e14dcfSSatish Balay .  J   - Jacobian matrix
524a7e14dcfSSatish Balay -  ctx - [optional] user-defined Jacobian context
525a7e14dcfSSatish Balay 
526a7e14dcfSSatish Balay    Level: intermediate
527f4c1ad5cSStefano Zampini 
528a7e14dcfSSatish Balay .seealso: TaoComputeJacobianDesign(), TaoSetJacobianStateRoutine(), TaoSetStateDesignIS()
529a7e14dcfSSatish Balay @*/
53094ab13aaSBarry Smith PetscErrorCode TaoSetJacobianDesignRoutine(Tao tao, Mat J, PetscErrorCode (*func)(Tao, Vec, Mat, void*), void *ctx)
531a7e14dcfSSatish Balay {
532a7e14dcfSSatish Balay   PetscErrorCode ierr;
53345cf516eSBarry Smith 
534a7e14dcfSSatish Balay   PetscFunctionBegin;
535441846f8SBarry Smith   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
536a7e14dcfSSatish Balay   if (J) {
537a7e14dcfSSatish Balay     PetscValidHeaderSpecific(J,MAT_CLASSID,2);
538a7e14dcfSSatish Balay     PetscCheckSameComm(tao,1,J,2);
539a7e14dcfSSatish Balay   }
540a7e14dcfSSatish Balay   if (ctx) {
541a7e14dcfSSatish Balay     tao->user_jac_designP = ctx;
542a7e14dcfSSatish Balay   }
543a7e14dcfSSatish Balay   if (func) {
544a7e14dcfSSatish Balay     tao->ops->computejacobiandesign = func;
545a7e14dcfSSatish Balay   }
546a7e14dcfSSatish Balay   if (J) {
547a7e14dcfSSatish Balay     ierr = PetscObjectReference((PetscObject)J);CHKERRQ(ierr);
54845cf516eSBarry Smith     ierr = MatDestroy(&tao->jacobian_design);CHKERRQ(ierr);
549a7e14dcfSSatish Balay     tao->jacobian_design = J;
550a7e14dcfSSatish Balay   }
551a7e14dcfSSatish Balay   PetscFunctionReturn(0);
552a7e14dcfSSatish Balay }
553a7e14dcfSSatish Balay 
554a7e14dcfSSatish Balay /*@
555441846f8SBarry Smith    TaoSetStateDesignIS - Indicate to the Tao which variables in the
556a7e14dcfSSatish Balay    solution vector are state variables and which are design.  Only applies to
557a7e14dcfSSatish Balay    pde-constrained optimization.
558a7e14dcfSSatish Balay 
559441846f8SBarry Smith    Logically Collective on Tao
560a7e14dcfSSatish Balay 
561a7e14dcfSSatish Balay    Input Parameters:
562441846f8SBarry Smith +  tao  - The Tao context
563a7e14dcfSSatish Balay .  s_is - the index set corresponding to the state variables
564a7e14dcfSSatish Balay -  d_is - the index set corresponding to the design variables
565a7e14dcfSSatish Balay 
566a7e14dcfSSatish Balay    Level: intermediate
567a7e14dcfSSatish Balay 
568a7e14dcfSSatish Balay .seealso: TaoSetJacobianStateRoutine(), TaoSetJacobianDesignRoutine()
569a7e14dcfSSatish Balay @*/
570441846f8SBarry Smith PetscErrorCode TaoSetStateDesignIS(Tao tao, IS s_is, IS d_is)
571a7e14dcfSSatish Balay {
572a7e14dcfSSatish Balay   PetscErrorCode ierr;
57345cf516eSBarry Smith 
57445cf516eSBarry Smith   PetscFunctionBegin;
57545cf516eSBarry Smith   ierr = PetscObjectReference((PetscObject)s_is);CHKERRQ(ierr);
57645cf516eSBarry Smith   ierr = ISDestroy(&tao->state_is);CHKERRQ(ierr);
577a7e14dcfSSatish Balay   tao->state_is = s_is;
57845cf516eSBarry Smith   ierr = PetscObjectReference((PetscObject)(d_is));CHKERRQ(ierr);
57945cf516eSBarry Smith   ierr = ISDestroy(&tao->design_is);CHKERRQ(ierr);
580a7e14dcfSSatish Balay   tao->design_is = d_is;
581a7e14dcfSSatish Balay   PetscFunctionReturn(0);
582a7e14dcfSSatish Balay }
583a7e14dcfSSatish Balay 
584a7e14dcfSSatish Balay /*@C
585a7e14dcfSSatish Balay    TaoComputeJacobianEquality - Computes the Jacobian matrix that has been
586a7e14dcfSSatish Balay    set with TaoSetJacobianEqualityRoutine().
587a7e14dcfSSatish Balay 
588441846f8SBarry Smith    Collective on Tao
589a7e14dcfSSatish Balay 
590a7e14dcfSSatish Balay    Input Parameters:
591f4c1ad5cSStefano Zampini +  tao - the Tao solver context
592f4c1ad5cSStefano Zampini -  X   - input vector
593a7e14dcfSSatish Balay 
594a7e14dcfSSatish Balay    Output Parameters:
595f4c1ad5cSStefano Zampini +  J    - Jacobian matrix
596f4c1ad5cSStefano Zampini -  Jpre - Preconditioning matrix
597a7e14dcfSSatish Balay 
598a7e14dcfSSatish Balay    Notes:
599a7e14dcfSSatish Balay    Most users should not need to explicitly call this routine, as it
600a7e14dcfSSatish Balay    is used internally within the minimization solvers.
601a7e14dcfSSatish Balay 
602a7e14dcfSSatish Balay    Level: developer
603a7e14dcfSSatish Balay 
604a7e14dcfSSatish Balay .seealso:  TaoComputeObjective(), TaoComputeObjectiveAndGradient(), TaoSetJacobianStateRoutine(), TaoComputeJacobianDesign(), TaoSetStateDesignIS()
605a7e14dcfSSatish Balay @*/
606ffad9901SBarry Smith PetscErrorCode TaoComputeJacobianEquality(Tao tao, Vec X, Mat J, Mat Jpre)
607a7e14dcfSSatish Balay {
608a7e14dcfSSatish Balay   PetscErrorCode ierr;
60945cf516eSBarry Smith 
610a7e14dcfSSatish Balay   PetscFunctionBegin;
611441846f8SBarry Smith   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
612a7e14dcfSSatish Balay   PetscValidHeaderSpecific(X, VEC_CLASSID,2);
613a7e14dcfSSatish Balay   PetscCheckSameComm(tao,1,X,2);
61487f595a5SBarry Smith   if (!tao->ops->computejacobianequality) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Must call TaoSetJacobianEquality() first");
615a7e14dcfSSatish Balay   ++tao->njac_equality;
616f4c1ad5cSStefano Zampini   ierr = VecLockPush(X);CHKERRQ(ierr);
61794ab13aaSBarry Smith   ierr = PetscLogEventBegin(Tao_JacobianEval,tao,X,J,Jpre);CHKERRQ(ierr);
618441846f8SBarry Smith   PetscStackPush("Tao user Jacobian(equality) function");
619ffad9901SBarry Smith   ierr = (*tao->ops->computejacobianequality)(tao,X,J,Jpre,tao->user_jac_equalityP);CHKERRQ(ierr);
620a7e14dcfSSatish Balay   PetscStackPop;
62194ab13aaSBarry Smith   ierr = PetscLogEventEnd(Tao_JacobianEval,tao,X,J,Jpre);CHKERRQ(ierr);
622f4c1ad5cSStefano Zampini   ierr = VecLockPop(X);CHKERRQ(ierr);
623a7e14dcfSSatish Balay   PetscFunctionReturn(0);
624a7e14dcfSSatish Balay }
625a7e14dcfSSatish Balay 
626a7e14dcfSSatish Balay /*@C
627a7e14dcfSSatish Balay    TaoComputeJacobianInequality - Computes the Jacobian matrix that has been
628a7e14dcfSSatish Balay    set with TaoSetJacobianInequalityRoutine().
629a7e14dcfSSatish Balay 
630441846f8SBarry Smith    Collective on Tao
631a7e14dcfSSatish Balay 
632a7e14dcfSSatish Balay    Input Parameters:
633f4c1ad5cSStefano Zampini +  tao - the Tao solver context
634f4c1ad5cSStefano Zampini -  X   - input vector
635a7e14dcfSSatish Balay 
636a7e14dcfSSatish Balay    Output Parameters:
637f4c1ad5cSStefano Zampini +  J    - Jacobian matrix
638f4c1ad5cSStefano Zampini -  Jpre - Preconditioning matrix
639a7e14dcfSSatish Balay 
640a7e14dcfSSatish Balay    Notes:
641a7e14dcfSSatish Balay    Most users should not need to explicitly call this routine, as it
642a7e14dcfSSatish Balay    is used internally within the minimization solvers.
643a7e14dcfSSatish Balay 
644a7e14dcfSSatish Balay    Level: developer
645a7e14dcfSSatish Balay 
646a7e14dcfSSatish Balay .seealso:  TaoComputeObjective(), TaoComputeObjectiveAndGradient(), TaoSetJacobianStateRoutine(), TaoComputeJacobianDesign(), TaoSetStateDesignIS()
647a7e14dcfSSatish Balay @*/
648ffad9901SBarry Smith PetscErrorCode TaoComputeJacobianInequality(Tao tao, Vec X, Mat J, Mat Jpre)
649a7e14dcfSSatish Balay {
650a7e14dcfSSatish Balay   PetscErrorCode ierr;
65187f595a5SBarry Smith 
652a7e14dcfSSatish Balay   PetscFunctionBegin;
653441846f8SBarry Smith   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
654a7e14dcfSSatish Balay   PetscValidHeaderSpecific(X, VEC_CLASSID,2);
655a7e14dcfSSatish Balay   PetscCheckSameComm(tao,1,X,2);
65687f595a5SBarry Smith   if (!tao->ops->computejacobianinequality) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Must call TaoSetJacobianInequality() first");
657a7e14dcfSSatish Balay   ++tao->njac_inequality;
658f4c1ad5cSStefano Zampini   ierr = VecLockPush(X);CHKERRQ(ierr);
65994ab13aaSBarry Smith   ierr = PetscLogEventBegin(Tao_JacobianEval,tao,X,J,Jpre);CHKERRQ(ierr);
660441846f8SBarry Smith   PetscStackPush("Tao user Jacobian(inequality) function");
661ffad9901SBarry Smith   ierr = (*tao->ops->computejacobianinequality)(tao,X,J,Jpre,tao->user_jac_inequalityP);CHKERRQ(ierr);
662a7e14dcfSSatish Balay   PetscStackPop;
66394ab13aaSBarry Smith   ierr = PetscLogEventEnd(Tao_JacobianEval,tao,X,J,Jpre);CHKERRQ(ierr);
664f4c1ad5cSStefano Zampini   ierr = VecLockPop(X);CHKERRQ(ierr);
665a7e14dcfSSatish Balay   PetscFunctionReturn(0);
666a7e14dcfSSatish Balay }
667a7e14dcfSSatish Balay 
668a7e14dcfSSatish Balay /*@C
669a7e14dcfSSatish Balay    TaoSetJacobianEqualityRoutine - Sets the function to compute the Jacobian
670a7e14dcfSSatish Balay    (and its inverse) of the constraint function with respect to the equality variables.
671a7e14dcfSSatish Balay    Used only for pde-constrained optimization.
672a7e14dcfSSatish Balay 
673441846f8SBarry Smith    Logically collective on Tao
674a7e14dcfSSatish Balay 
675a7e14dcfSSatish Balay    Input Parameters:
676441846f8SBarry Smith +  tao  - the Tao context
677a7e14dcfSSatish Balay .  J    - Matrix used for the jacobian
678a7e14dcfSSatish Balay .  Jpre - Matrix that will be used operated on by PETSc preconditioner, can be same as J.
679f4c1ad5cSStefano Zampini .  func - Jacobian evaluation routine
680a7e14dcfSSatish Balay -  ctx  - [optional] user-defined context for private data for the
6816c23d075SBarry Smith           Jacobian evaluation routine (may be NULL)
682a7e14dcfSSatish Balay 
683f4c1ad5cSStefano Zampini    Calling sequence of func:
684f4c1ad5cSStefano Zampini $    func(Tao tao,Vec x,Mat J,Mat Jpre,void *ctx);
685a7e14dcfSSatish Balay 
686441846f8SBarry Smith +  tao  - the Tao  context
687a7e14dcfSSatish Balay .  x    - input vector
688a7e14dcfSSatish Balay .  J    - Jacobian matrix
689a7e14dcfSSatish Balay .  Jpre - preconditioner matrix, usually the same as J
690a7e14dcfSSatish Balay -  ctx  - [optional] user-defined Jacobian context
691a7e14dcfSSatish Balay 
692a7e14dcfSSatish Balay    Level: intermediate
693f4c1ad5cSStefano Zampini 
694f4c1ad5cSStefano Zampini .seealso: TaoComputeJacobianEquality(), TaoSetJacobianDesignRoutine(), TaoSetEqualityDesignIS()
695a7e14dcfSSatish Balay @*/
696ffad9901SBarry Smith PetscErrorCode TaoSetJacobianEqualityRoutine(Tao tao, Mat J, Mat Jpre, PetscErrorCode (*func)(Tao, Vec, Mat, Mat,void*), void *ctx)
697a7e14dcfSSatish Balay {
698a7e14dcfSSatish Balay   PetscErrorCode ierr;
69945cf516eSBarry Smith 
700a7e14dcfSSatish Balay   PetscFunctionBegin;
701441846f8SBarry Smith   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
702a7e14dcfSSatish Balay   if (J) {
703a7e14dcfSSatish Balay     PetscValidHeaderSpecific(J,MAT_CLASSID,2);
704a7e14dcfSSatish Balay     PetscCheckSameComm(tao,1,J,2);
705a7e14dcfSSatish Balay   }
706a7e14dcfSSatish Balay   if (Jpre) {
707a7e14dcfSSatish Balay     PetscValidHeaderSpecific(Jpre,MAT_CLASSID,3);
708a7e14dcfSSatish Balay     PetscCheckSameComm(tao,1,Jpre,3);
709a7e14dcfSSatish Balay   }
710a7e14dcfSSatish Balay   if (ctx) {
711a7e14dcfSSatish Balay     tao->user_jac_equalityP = ctx;
712a7e14dcfSSatish Balay   }
713a7e14dcfSSatish Balay   if (func) {
714a7e14dcfSSatish Balay     tao->ops->computejacobianequality = func;
715a7e14dcfSSatish Balay   }
716a7e14dcfSSatish Balay   if (J) {
717a7e14dcfSSatish Balay     ierr = PetscObjectReference((PetscObject)J);CHKERRQ(ierr);
71845cf516eSBarry Smith     ierr = MatDestroy(&tao->jacobian_equality);CHKERRQ(ierr);
719a7e14dcfSSatish Balay     tao->jacobian_equality = J;
720a7e14dcfSSatish Balay   }
721a7e14dcfSSatish Balay   if (Jpre) {
722a7e14dcfSSatish Balay     ierr = PetscObjectReference((PetscObject)Jpre);CHKERRQ(ierr);
72345cf516eSBarry Smith     ierr = MatDestroy(&tao->jacobian_equality_pre);CHKERRQ(ierr);
724a7e14dcfSSatish Balay     tao->jacobian_equality_pre=Jpre;
725a7e14dcfSSatish Balay   }
726a7e14dcfSSatish Balay   PetscFunctionReturn(0);
727a7e14dcfSSatish Balay }
728a7e14dcfSSatish Balay 
729a7e14dcfSSatish Balay /*@C
730a7e14dcfSSatish Balay    TaoSetJacobianInequalityRoutine - Sets the function to compute the Jacobian
731a7e14dcfSSatish Balay    (and its inverse) of the constraint function with respect to the inequality variables.
732a7e14dcfSSatish Balay    Used only for pde-constrained optimization.
733a7e14dcfSSatish Balay 
734441846f8SBarry Smith    Logically collective on Tao
735a7e14dcfSSatish Balay 
736a7e14dcfSSatish Balay    Input Parameters:
737441846f8SBarry Smith +  tao  - the Tao context
738a7e14dcfSSatish Balay .  J    - Matrix used for the jacobian
739a7e14dcfSSatish Balay .  Jpre - Matrix that will be used operated on by PETSc preconditioner, can be same as J.
740f4c1ad5cSStefano Zampini .  func - Jacobian evaluation routine
741a7e14dcfSSatish Balay -  ctx  - [optional] user-defined context for private data for the
7426c23d075SBarry Smith           Jacobian evaluation routine (may be NULL)
743a7e14dcfSSatish Balay 
744f4c1ad5cSStefano Zampini    Calling sequence of func:
745f4c1ad5cSStefano Zampini $    func(Tao tao,Vec x,Mat J,Mat Jpre,void *ctx);
746a7e14dcfSSatish Balay 
747441846f8SBarry Smith +  tao  - the Tao  context
748a7e14dcfSSatish Balay .  x    - input vector
749a7e14dcfSSatish Balay .  J    - Jacobian matrix
750a7e14dcfSSatish Balay .  Jpre - preconditioner matrix, usually the same as J
751a7e14dcfSSatish Balay -  ctx  - [optional] user-defined Jacobian context
752a7e14dcfSSatish Balay 
753a7e14dcfSSatish Balay    Level: intermediate
754f4c1ad5cSStefano Zampini 
755f4c1ad5cSStefano Zampini .seealso: TaoComputeJacobianInequality(), TaoSetJacobianDesignRoutine(), TaoSetInequalityDesignIS()
756a7e14dcfSSatish Balay @*/
757ffad9901SBarry Smith PetscErrorCode TaoSetJacobianInequalityRoutine(Tao tao, Mat J, Mat Jpre, PetscErrorCode (*func)(Tao, Vec, Mat, Mat,void*), void *ctx)
758a7e14dcfSSatish Balay {
759a7e14dcfSSatish Balay   PetscErrorCode ierr;
760f4c1ad5cSStefano Zampini 
761a7e14dcfSSatish Balay   PetscFunctionBegin;
762441846f8SBarry Smith   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
763a7e14dcfSSatish Balay   if (J) {
764a7e14dcfSSatish Balay     PetscValidHeaderSpecific(J,MAT_CLASSID,2);
765a7e14dcfSSatish Balay     PetscCheckSameComm(tao,1,J,2);
766a7e14dcfSSatish Balay   }
767a7e14dcfSSatish Balay   if (Jpre) {
768a7e14dcfSSatish Balay     PetscValidHeaderSpecific(Jpre,MAT_CLASSID,3);
769a7e14dcfSSatish Balay     PetscCheckSameComm(tao,1,Jpre,3);
770a7e14dcfSSatish Balay   }
771a7e14dcfSSatish Balay   if (ctx) {
772a7e14dcfSSatish Balay     tao->user_jac_inequalityP = ctx;
773a7e14dcfSSatish Balay   }
774a7e14dcfSSatish Balay   if (func) {
775a7e14dcfSSatish Balay     tao->ops->computejacobianinequality = func;
776a7e14dcfSSatish Balay   }
777a7e14dcfSSatish Balay   if (J) {
778a7e14dcfSSatish Balay     ierr = PetscObjectReference((PetscObject)J);CHKERRQ(ierr);
77945cf516eSBarry Smith     ierr = MatDestroy(&tao->jacobian_inequality);CHKERRQ(ierr);
780a7e14dcfSSatish Balay     tao->jacobian_inequality = J;
781a7e14dcfSSatish Balay   }
782a7e14dcfSSatish Balay   if (Jpre) {
783a7e14dcfSSatish Balay     ierr = PetscObjectReference((PetscObject)Jpre);CHKERRQ(ierr);
78445cf516eSBarry Smith     ierr = MatDestroy(&tao->jacobian_inequality_pre);CHKERRQ(ierr);
785a7e14dcfSSatish Balay     tao->jacobian_inequality_pre=Jpre;
786a7e14dcfSSatish Balay   }
787a7e14dcfSSatish Balay   PetscFunctionReturn(0);
788a7e14dcfSSatish Balay }
789