xref: /petsc/src/tao/interface/taosolver_hj.c (revision 6b867d5ac32ed0c728f185df9d084acdf26f70bf)
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 
6009baa881SHong Zhang PetscErrorCode TaoTestHessian(Tao tao)
6109baa881SHong Zhang {
6209baa881SHong Zhang   Mat               A,B,C,D,hessian;
6309baa881SHong Zhang   Vec               x = tao->solution;
6409baa881SHong Zhang   PetscErrorCode    ierr;
6509baa881SHong Zhang   PetscReal         nrm,gnorm;
6609baa881SHong Zhang   PetscReal         threshold = 1.e-5;
6709baa881SHong Zhang   PetscInt          m,n,M,N;
6809baa881SHong Zhang   PetscBool         complete_print = PETSC_FALSE,test = PETSC_FALSE,flg;
69f49d1c87SHong Zhang   PetscViewer       viewer,mviewer;
7009baa881SHong Zhang   MPI_Comm          comm;
7109baa881SHong Zhang   PetscInt          tabs;
7209baa881SHong Zhang   static PetscBool  directionsprinted = PETSC_FALSE;
73f49d1c87SHong Zhang   PetscViewerFormat format;
7409baa881SHong Zhang 
7509baa881SHong Zhang   PetscFunctionBegin;
7609baa881SHong Zhang   ierr = PetscObjectOptionsBegin((PetscObject)tao);CHKERRQ(ierr);
7709baa881SHong Zhang   ierr = PetscOptionsName("-tao_test_hessian","Compare hand-coded and finite difference Hessians","None",&test);CHKERRQ(ierr);
7809baa881SHong Zhang   ierr = PetscOptionsReal("-tao_test_hessian", "Threshold for element difference between hand-coded and finite difference being meaningful","None",threshold,&threshold,NULL);CHKERRQ(ierr);
79f49d1c87SHong Zhang   ierr = PetscOptionsViewer("-tao_test_hessian_view","View difference between hand-coded and finite difference Hessians element entries","None",&mviewer,&format,&complete_print);CHKERRQ(ierr);
8009baa881SHong Zhang   ierr = PetscOptionsEnd();CHKERRQ(ierr);
8109baa881SHong Zhang   if (!test) PetscFunctionReturn(0);
8209baa881SHong Zhang 
8309baa881SHong Zhang   ierr = PetscObjectGetComm((PetscObject)tao,&comm);CHKERRQ(ierr);
8409baa881SHong Zhang   ierr = PetscViewerASCIIGetStdout(comm,&viewer);CHKERRQ(ierr);
8509baa881SHong Zhang   ierr = PetscViewerASCIIGetTab(viewer, &tabs);CHKERRQ(ierr);
8609baa881SHong Zhang   ierr = PetscViewerASCIISetTab(viewer, ((PetscObject)tao)->tablevel);CHKERRQ(ierr);
8709baa881SHong Zhang   ierr = PetscViewerASCIIPrintf(viewer,"  ---------- Testing Hessian -------------\n");CHKERRQ(ierr);
8809baa881SHong Zhang   if (!complete_print && !directionsprinted) {
8909baa881SHong Zhang     ierr = PetscViewerASCIIPrintf(viewer,"  Run with -tao_test_hessian_view and optionally -tao_test_hessian <threshold> to show difference\n");CHKERRQ(ierr);
9009baa881SHong Zhang     ierr = PetscViewerASCIIPrintf(viewer,"    of hand-coded and finite difference Hessian entries greater than <threshold>.\n");CHKERRQ(ierr);
9109baa881SHong Zhang   }
9209baa881SHong Zhang   if (!directionsprinted) {
9309baa881SHong Zhang     ierr = PetscViewerASCIIPrintf(viewer,"  Testing hand-coded Hessian, if (for double precision runs) ||J - Jfd||_F/||J||_F is\n");CHKERRQ(ierr);
9409baa881SHong Zhang     ierr = PetscViewerASCIIPrintf(viewer,"    O(1.e-8), the hand-coded Hessian is probably correct.\n");CHKERRQ(ierr);
9509baa881SHong Zhang     directionsprinted = PETSC_TRUE;
9609baa881SHong Zhang   }
97f49d1c87SHong Zhang   if (complete_print) {
98f49d1c87SHong Zhang     ierr = PetscViewerPushFormat(mviewer,format);CHKERRQ(ierr);
99f49d1c87SHong Zhang   }
10009baa881SHong Zhang 
10109baa881SHong Zhang   ierr = PetscObjectTypeCompare((PetscObject)tao->hessian,MATMFFD,&flg);CHKERRQ(ierr);
10209baa881SHong Zhang   if (!flg) hessian = tao->hessian;
10309baa881SHong Zhang   else hessian = tao->hessian_pre;
10409baa881SHong Zhang 
10509baa881SHong Zhang   while (hessian) {
106b9e7e5c1SBarry Smith     ierr = PetscObjectBaseTypeCompareAny((PetscObject)hessian,&flg,MATSEQAIJ,MATMPIAIJ,MATSEQDENSE,MATMPIDENSE,MATSEQBAIJ,MATMPIBAIJ,MATSEQSBAIJ,MATMPIBAIJ,"");CHKERRQ(ierr);
10709baa881SHong Zhang     if (flg) {
10809baa881SHong Zhang       A    = hessian;
10909baa881SHong Zhang       ierr = PetscObjectReference((PetscObject)A);CHKERRQ(ierr);
11009baa881SHong Zhang     } else {
1110bacdadaSStefano Zampini       ierr = MatComputeOperator(hessian,MATAIJ,&A);CHKERRQ(ierr);
11209baa881SHong Zhang     }
11309baa881SHong Zhang 
11409baa881SHong Zhang     ierr = MatCreate(PetscObjectComm((PetscObject)A),&B);CHKERRQ(ierr);
11509baa881SHong Zhang     ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
11609baa881SHong Zhang     ierr = MatGetLocalSize(A,&m,&n);CHKERRQ(ierr);
11709baa881SHong Zhang     ierr = MatSetSizes(B,m,n,M,N);CHKERRQ(ierr);
11809baa881SHong Zhang     ierr = MatSetType(B,((PetscObject)A)->type_name);CHKERRQ(ierr);
11909baa881SHong Zhang     ierr = MatSetUp(B);CHKERRQ(ierr);
12009baa881SHong Zhang     ierr = MatSetOption(B,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_FALSE);CHKERRQ(ierr);
12109baa881SHong Zhang 
12209baa881SHong Zhang     ierr = TaoDefaultComputeHessian(tao,x,B,B,NULL);CHKERRQ(ierr);
12309baa881SHong Zhang 
12409baa881SHong Zhang     ierr = MatDuplicate(B,MAT_COPY_VALUES,&D);CHKERRQ(ierr);
12509baa881SHong Zhang     ierr = MatAYPX(D,-1.0,A,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr);
12609baa881SHong Zhang     ierr = MatNorm(D,NORM_FROBENIUS,&nrm);CHKERRQ(ierr);
12709baa881SHong Zhang     ierr = MatNorm(A,NORM_FROBENIUS,&gnorm);CHKERRQ(ierr);
12809baa881SHong Zhang     ierr = MatDestroy(&D);CHKERRQ(ierr);
12909baa881SHong Zhang     if (!gnorm) gnorm = 1; /* just in case */
13009baa881SHong Zhang     ierr = PetscViewerASCIIPrintf(viewer,"  ||H - Hfd||_F/||H||_F = %g, ||H - Hfd||_F = %g\n",(double)(nrm/gnorm),(double)nrm);CHKERRQ(ierr);
13109baa881SHong Zhang 
13209baa881SHong Zhang     if (complete_print) {
13309baa881SHong Zhang       ierr = PetscViewerASCIIPrintf(viewer,"  Hand-coded Hessian ----------\n");CHKERRQ(ierr);
134f3b6e7e3SStefano Zampini       ierr = MatView(A,mviewer);CHKERRQ(ierr);
13509baa881SHong Zhang       ierr = PetscViewerASCIIPrintf(viewer,"  Finite difference Hessian ----------\n");CHKERRQ(ierr);
136f49d1c87SHong Zhang       ierr = MatView(B,mviewer);CHKERRQ(ierr);
13709baa881SHong Zhang     }
13809baa881SHong Zhang 
13909baa881SHong Zhang     if (complete_print) {
14009baa881SHong Zhang       PetscInt          Istart, Iend, *ccols, bncols, cncols, j, row;
14109baa881SHong Zhang       PetscScalar       *cvals;
14209baa881SHong Zhang       const PetscInt    *bcols;
14309baa881SHong Zhang       const PetscScalar *bvals;
14409baa881SHong Zhang 
14509baa881SHong Zhang       ierr = MatAYPX(B,-1.0,A,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr);
14609baa881SHong Zhang       ierr = MatCreate(PetscObjectComm((PetscObject)A),&C);CHKERRQ(ierr);
14709baa881SHong Zhang       ierr = MatSetSizes(C,m,n,M,N);CHKERRQ(ierr);
14809baa881SHong Zhang       ierr = MatSetType(C,((PetscObject)A)->type_name);CHKERRQ(ierr);
14909baa881SHong Zhang       ierr = MatSetUp(C);CHKERRQ(ierr);
15009baa881SHong Zhang       ierr = MatSetOption(C,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_FALSE);CHKERRQ(ierr);
15109baa881SHong Zhang       ierr = MatGetOwnershipRange(B,&Istart,&Iend);CHKERRQ(ierr);
15209baa881SHong Zhang 
15309baa881SHong Zhang       for (row = Istart; row < Iend; row++) {
15409baa881SHong Zhang         ierr = MatGetRow(B,row,&bncols,&bcols,&bvals);CHKERRQ(ierr);
15509baa881SHong Zhang         ierr = PetscMalloc2(bncols,&ccols,bncols,&cvals);CHKERRQ(ierr);
15609baa881SHong Zhang         for (j = 0, cncols = 0; j < bncols; j++) {
15709baa881SHong Zhang           if (PetscAbsScalar(bvals[j]) > threshold) {
15809baa881SHong Zhang             ccols[cncols] = bcols[j];
15909baa881SHong Zhang             cvals[cncols] = bvals[j];
16009baa881SHong Zhang             cncols += 1;
16109baa881SHong Zhang           }
16209baa881SHong Zhang         }
16309baa881SHong Zhang         if (cncols) {
16409baa881SHong Zhang           ierr = MatSetValues(C,1,&row,cncols,ccols,cvals,INSERT_VALUES);CHKERRQ(ierr);
16509baa881SHong Zhang         }
16609baa881SHong Zhang         ierr = MatRestoreRow(B,row,&bncols,&bcols,&bvals);CHKERRQ(ierr);
16709baa881SHong Zhang         ierr = PetscFree2(ccols,cvals);CHKERRQ(ierr);
16809baa881SHong Zhang       }
16909baa881SHong Zhang       ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
17009baa881SHong Zhang       ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
17109baa881SHong Zhang       ierr = PetscViewerASCIIPrintf(viewer,"  Finite-difference minus hand-coded Hessian with tolerance %g ----------\n",(double)threshold);CHKERRQ(ierr);
172f49d1c87SHong Zhang       ierr = MatView(C,mviewer);CHKERRQ(ierr);
17309baa881SHong Zhang       ierr = MatDestroy(&C);CHKERRQ(ierr);
17409baa881SHong Zhang     }
17509baa881SHong Zhang     ierr = MatDestroy(&A);CHKERRQ(ierr);
17609baa881SHong Zhang     ierr = MatDestroy(&B);CHKERRQ(ierr);
17709baa881SHong Zhang 
17809baa881SHong Zhang     if (hessian != tao->hessian_pre) {
17909baa881SHong Zhang       hessian = tao->hessian_pre;
18009baa881SHong Zhang       ierr = PetscViewerASCIIPrintf(viewer,"  ---------- Testing Hessian for preconditioner -------------\n");CHKERRQ(ierr);
18109baa881SHong Zhang     } else hessian = NULL;
18209baa881SHong Zhang   }
183f49d1c87SHong Zhang   if (complete_print) {
184f49d1c87SHong Zhang     ierr = PetscViewerPopFormat(mviewer);CHKERRQ(ierr);
18554b73907SStefano Zampini     ierr = PetscViewerDestroy(&mviewer);CHKERRQ(ierr);
186f49d1c87SHong Zhang   }
18709baa881SHong Zhang   ierr = PetscViewerASCIISetTab(viewer,tabs);CHKERRQ(ierr);
18809baa881SHong Zhang   PetscFunctionReturn(0);
18909baa881SHong Zhang }
19009baa881SHong Zhang 
191a7e14dcfSSatish Balay /*@C
192a7e14dcfSSatish Balay    TaoComputeHessian - Computes the Hessian matrix that has been
193a7e14dcfSSatish Balay    set with TaoSetHessianRoutine().
194a7e14dcfSSatish Balay 
195441846f8SBarry Smith    Collective on Tao
196a7e14dcfSSatish Balay 
197a7e14dcfSSatish Balay    Input Parameters:
198f4c1ad5cSStefano Zampini +  tao - the Tao solver context
199f4c1ad5cSStefano Zampini -  X   - input vector
200a7e14dcfSSatish Balay 
201a7e14dcfSSatish Balay    Output Parameters:
202a7e14dcfSSatish Balay +  H    - Hessian matrix
203aa6c7ce3SBarry Smith -  Hpre - Preconditioning matrix
204a7e14dcfSSatish Balay 
20509baa881SHong Zhang    Options Database Keys:
20609baa881SHong Zhang +     -tao_test_hessian - compare the user provided Hessian with one compute via finite differences to check for errors
20709baa881SHong 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
208dfe02fe6SHong Zhang -     -tao_test_hessian_view - 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
20909baa881SHong Zhang 
210a7e14dcfSSatish Balay    Notes:
211a7e14dcfSSatish Balay    Most users should not need to explicitly call this routine, as it
212a7e14dcfSSatish Balay    is used internally within the minimization solvers.
213a7e14dcfSSatish Balay 
214a7e14dcfSSatish Balay    TaoComputeHessian() is typically used within minimization
215a7e14dcfSSatish Balay    implementations, so most users would not generally call this routine
216a7e14dcfSSatish Balay    themselves.
217a7e14dcfSSatish Balay 
21809baa881SHong Zhang    Developer Notes:
21909baa881SHong Zhang    The Hessian test mechanism follows SNESTestJacobian().
22009baa881SHong Zhang 
221a7e14dcfSSatish Balay    Level: developer
222a7e14dcfSSatish Balay 
223f4c1ad5cSStefano Zampini .seealso: TaoComputeObjective(), TaoComputeObjectiveAndGradient(), TaoSetHessianRoutine()
224a7e14dcfSSatish Balay @*/
225ffad9901SBarry Smith PetscErrorCode TaoComputeHessian(Tao tao, Vec X, Mat H, Mat Hpre)
226a7e14dcfSSatish Balay {
227a7e14dcfSSatish Balay   PetscErrorCode ierr;
22887f595a5SBarry Smith 
229a7e14dcfSSatish Balay   PetscFunctionBegin;
230441846f8SBarry Smith   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
231a7e14dcfSSatish Balay   PetscValidHeaderSpecific(X, VEC_CLASSID,2);
232a7e14dcfSSatish Balay   PetscCheckSameComm(tao,1,X,2);
233f4c1ad5cSStefano Zampini   if (!tao->ops->computehessian) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Must call TaoSetHessianRoutine() first");
234a7e14dcfSSatish Balay   ++tao->nhess;
2358860a134SJunchao Zhang   ierr = VecLockReadPush(X);CHKERRQ(ierr);
2360ebee16dSLisandro Dalcin   ierr = PetscLogEventBegin(TAO_HessianEval,tao,X,H,Hpre);CHKERRQ(ierr);
237441846f8SBarry Smith   PetscStackPush("Tao user Hessian function");
238ffad9901SBarry Smith   ierr = (*tao->ops->computehessian)(tao,X,H,Hpre,tao->user_hessP);CHKERRQ(ierr);
239a7e14dcfSSatish Balay   PetscStackPop;
2400ebee16dSLisandro Dalcin   ierr = PetscLogEventEnd(TAO_HessianEval,tao,X,H,Hpre);CHKERRQ(ierr);
2418860a134SJunchao Zhang   ierr = VecLockReadPop(X);CHKERRQ(ierr);
24209baa881SHong Zhang 
24309baa881SHong Zhang   ierr = TaoTestHessian(tao);CHKERRQ(ierr);
244a7e14dcfSSatish Balay   PetscFunctionReturn(0);
245a7e14dcfSSatish Balay }
246a7e14dcfSSatish Balay 
247a7e14dcfSSatish Balay /*@C
248a7e14dcfSSatish Balay    TaoComputeJacobian - Computes the Jacobian matrix that has been
249a7e14dcfSSatish Balay    set with TaoSetJacobianRoutine().
250a7e14dcfSSatish Balay 
251441846f8SBarry Smith    Collective on Tao
252a7e14dcfSSatish Balay 
253a7e14dcfSSatish Balay    Input Parameters:
254f4c1ad5cSStefano Zampini +  tao - the Tao solver context
255f4c1ad5cSStefano Zampini -  X   - input vector
256a7e14dcfSSatish Balay 
257a7e14dcfSSatish Balay    Output Parameters:
258f4c1ad5cSStefano Zampini +  J    - Jacobian matrix
259f4c1ad5cSStefano Zampini -  Jpre - Preconditioning matrix
260a7e14dcfSSatish Balay 
261a7e14dcfSSatish Balay    Notes:
262a7e14dcfSSatish Balay    Most users should not need to explicitly call this routine, as it
263a7e14dcfSSatish Balay    is used internally within the minimization solvers.
264a7e14dcfSSatish Balay 
265a7e14dcfSSatish Balay    TaoComputeJacobian() is typically used within minimization
266a7e14dcfSSatish Balay    implementations, so most users would not generally call this routine
267a7e14dcfSSatish Balay    themselves.
268a7e14dcfSSatish Balay 
269a7e14dcfSSatish Balay    Level: developer
270a7e14dcfSSatish Balay 
271f4c1ad5cSStefano Zampini .seealso: TaoComputeObjective(), TaoComputeObjectiveAndGradient(), TaoSetJacobianRoutine()
272a7e14dcfSSatish Balay @*/
273ffad9901SBarry Smith PetscErrorCode TaoComputeJacobian(Tao tao, Vec X, Mat J, Mat Jpre)
274a7e14dcfSSatish Balay {
275a7e14dcfSSatish Balay   PetscErrorCode ierr;
27687f595a5SBarry Smith 
277a7e14dcfSSatish Balay   PetscFunctionBegin;
278441846f8SBarry Smith   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
279a7e14dcfSSatish Balay   PetscValidHeaderSpecific(X, VEC_CLASSID,2);
280a7e14dcfSSatish Balay   PetscCheckSameComm(tao,1,X,2);
28187f595a5SBarry Smith   if (!tao->ops->computejacobian) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Must call TaoSetJacobian() first");
282a7e14dcfSSatish Balay   ++tao->njac;
2838860a134SJunchao Zhang   ierr = VecLockReadPush(X);CHKERRQ(ierr);
2840ebee16dSLisandro Dalcin   ierr = PetscLogEventBegin(TAO_JacobianEval,tao,X,J,Jpre);CHKERRQ(ierr);
285441846f8SBarry Smith   PetscStackPush("Tao user Jacobian function");
286ffad9901SBarry Smith   ierr = (*tao->ops->computejacobian)(tao,X,J,Jpre,tao->user_jacP);CHKERRQ(ierr);
287a7e14dcfSSatish Balay   PetscStackPop;
2880ebee16dSLisandro Dalcin   ierr = PetscLogEventEnd(TAO_JacobianEval,tao,X,J,Jpre);CHKERRQ(ierr);
2898860a134SJunchao Zhang   ierr = VecLockReadPop(X);CHKERRQ(ierr);
290a7e14dcfSSatish Balay   PetscFunctionReturn(0);
291a7e14dcfSSatish Balay }
292a7e14dcfSSatish Balay 
293a7e14dcfSSatish Balay /*@C
2944a48860cSAlp Dener    TaoComputeResidualJacobian - Computes the least-squares residual Jacobian matrix that has been
295a6fed868SAlp Dener    set with TaoSetJacobianResidual().
2964a48860cSAlp Dener 
2974a48860cSAlp Dener    Collective on Tao
2984a48860cSAlp Dener 
2994a48860cSAlp Dener    Input Parameters:
3004a48860cSAlp Dener +  tao - the Tao solver context
3014a48860cSAlp Dener -  X   - input vector
3024a48860cSAlp Dener 
3034a48860cSAlp Dener    Output Parameters:
3044a48860cSAlp Dener +  J    - Jacobian matrix
3054a48860cSAlp Dener -  Jpre - Preconditioning matrix
3064a48860cSAlp Dener 
3074a48860cSAlp Dener    Notes:
3084a48860cSAlp Dener    Most users should not need to explicitly call this routine, as it
3094a48860cSAlp Dener    is used internally within the minimization solvers.
3104a48860cSAlp Dener 
3114a48860cSAlp Dener    TaoComputeResidualJacobian() is typically used within least-squares
3124a48860cSAlp Dener    implementations, so most users would not generally call this routine
3134a48860cSAlp Dener    themselves.
3144a48860cSAlp Dener 
3154a48860cSAlp Dener    Level: developer
3164a48860cSAlp Dener 
317a6fed868SAlp Dener .seealso: TaoComputeResidual(), TaoSetJacobianResidual()
3184a48860cSAlp Dener @*/
3194a48860cSAlp Dener PetscErrorCode TaoComputeResidualJacobian(Tao tao, Vec X, Mat J, Mat Jpre)
3204a48860cSAlp Dener {
3214a48860cSAlp Dener   PetscErrorCode ierr;
3224a48860cSAlp Dener 
3234a48860cSAlp Dener   PetscFunctionBegin;
3244a48860cSAlp Dener   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
3254a48860cSAlp Dener   PetscValidHeaderSpecific(X, VEC_CLASSID,2);
3264a48860cSAlp Dener   PetscCheckSameComm(tao,1,X,2);
3274a48860cSAlp Dener   if (!tao->ops->computeresidualjacobian) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Must call TaoSetResidualJacobian() first");
3284a48860cSAlp Dener   ++tao->njac;
3298860a134SJunchao Zhang   ierr = VecLockReadPush(X);CHKERRQ(ierr);
3304a48860cSAlp Dener   ierr = PetscLogEventBegin(TAO_JacobianEval,tao,X,J,Jpre);CHKERRQ(ierr);
3314a48860cSAlp Dener   PetscStackPush("Tao user least-squares residual Jacobian function");
3324a48860cSAlp Dener   ierr = (*tao->ops->computeresidualjacobian)(tao,X,J,Jpre,tao->user_lsjacP);CHKERRQ(ierr);
3334a48860cSAlp Dener   PetscStackPop;
3344a48860cSAlp Dener   ierr = PetscLogEventEnd(TAO_JacobianEval,tao,X,J,Jpre);CHKERRQ(ierr);
3358860a134SJunchao Zhang   ierr = VecLockReadPop(X);CHKERRQ(ierr);
3364a48860cSAlp Dener   PetscFunctionReturn(0);
3374a48860cSAlp Dener }
3384a48860cSAlp Dener 
3394a48860cSAlp Dener /*@C
340a7e14dcfSSatish Balay    TaoComputeJacobianState - Computes the Jacobian matrix that has been
341a7e14dcfSSatish Balay    set with TaoSetJacobianStateRoutine().
342a7e14dcfSSatish Balay 
343441846f8SBarry Smith    Collective on Tao
344a7e14dcfSSatish Balay 
345a7e14dcfSSatish Balay    Input Parameters:
346f4c1ad5cSStefano Zampini +  tao - the Tao solver context
347f4c1ad5cSStefano Zampini -  X   - input vector
348a7e14dcfSSatish Balay 
349a7e14dcfSSatish Balay    Output Parameters:
350*6b867d5aSJose E. Roman +  J    - Jacobian matrix
351*6b867d5aSJose E. Roman .  Jpre - Preconditioning matrix
352*6b867d5aSJose E. Roman -  Jinv -
353a7e14dcfSSatish Balay 
354a7e14dcfSSatish Balay    Notes:
355a7e14dcfSSatish Balay    Most users should not need to explicitly call this routine, as it
356a7e14dcfSSatish Balay    is used internally within the minimization solvers.
357a7e14dcfSSatish Balay 
358a7e14dcfSSatish Balay    TaoComputeJacobianState() is typically used within minimization
359a7e14dcfSSatish Balay    implementations, so most users would not generally call this routine
360a7e14dcfSSatish Balay    themselves.
361a7e14dcfSSatish Balay 
362a7e14dcfSSatish Balay    Level: developer
363a7e14dcfSSatish Balay 
364a7e14dcfSSatish Balay .seealso: TaoComputeObjective(), TaoComputeObjectiveAndGradient(), TaoSetJacobianStateRoutine(), TaoComputeJacobianDesign(), TaoSetStateDesignIS()
365a7e14dcfSSatish Balay @*/
366ffad9901SBarry Smith PetscErrorCode TaoComputeJacobianState(Tao tao, Vec X, Mat J, Mat Jpre, Mat Jinv)
367a7e14dcfSSatish Balay {
368a7e14dcfSSatish Balay   PetscErrorCode ierr;
36945cf516eSBarry Smith 
370a7e14dcfSSatish Balay   PetscFunctionBegin;
371441846f8SBarry Smith   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
372a7e14dcfSSatish Balay   PetscValidHeaderSpecific(X, VEC_CLASSID,2);
373a7e14dcfSSatish Balay   PetscCheckSameComm(tao,1,X,2);
37487f595a5SBarry Smith   if (!tao->ops->computejacobianstate) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Must call TaoSetJacobianState() first");
375a7e14dcfSSatish Balay   ++tao->njac_state;
3768860a134SJunchao Zhang   ierr = VecLockReadPush(X);CHKERRQ(ierr);
3770ebee16dSLisandro Dalcin   ierr = PetscLogEventBegin(TAO_JacobianEval,tao,X,J,Jpre);CHKERRQ(ierr);
378441846f8SBarry Smith   PetscStackPush("Tao user Jacobian(state) function");
379ffad9901SBarry Smith   ierr = (*tao->ops->computejacobianstate)(tao,X,J,Jpre,Jinv,tao->user_jac_stateP);CHKERRQ(ierr);
380a7e14dcfSSatish Balay   PetscStackPop;
3810ebee16dSLisandro Dalcin   ierr = PetscLogEventEnd(TAO_JacobianEval,tao,X,J,Jpre);CHKERRQ(ierr);
3828860a134SJunchao Zhang   ierr = VecLockReadPop(X);CHKERRQ(ierr);
383a7e14dcfSSatish Balay   PetscFunctionReturn(0);
384a7e14dcfSSatish Balay }
385a7e14dcfSSatish Balay 
386a7e14dcfSSatish Balay /*@C
387a7e14dcfSSatish Balay    TaoComputeJacobianDesign - Computes the Jacobian matrix that has been
388a7e14dcfSSatish Balay    set with TaoSetJacobianDesignRoutine().
389a7e14dcfSSatish Balay 
390441846f8SBarry Smith    Collective on Tao
391a7e14dcfSSatish Balay 
392a7e14dcfSSatish Balay    Input Parameters:
393f4c1ad5cSStefano Zampini +  tao - the Tao solver context
394f4c1ad5cSStefano Zampini -  X   - input vector
395a7e14dcfSSatish Balay 
396a7e14dcfSSatish Balay    Output Parameters:
397f4c1ad5cSStefano Zampini .  J - Jacobian matrix
398a7e14dcfSSatish Balay 
399a7e14dcfSSatish Balay    Notes:
400a7e14dcfSSatish Balay    Most users should not need to explicitly call this routine, as it
401a7e14dcfSSatish Balay    is used internally within the minimization solvers.
402a7e14dcfSSatish Balay 
403a7e14dcfSSatish Balay    TaoComputeJacobianDesign() is typically used within minimization
404a7e14dcfSSatish Balay    implementations, so most users would not generally call this routine
405a7e14dcfSSatish Balay    themselves.
406a7e14dcfSSatish Balay 
407a7e14dcfSSatish Balay    Level: developer
408a7e14dcfSSatish Balay 
409a7e14dcfSSatish Balay .seealso:  TaoComputeObjective(), TaoComputeObjectiveAndGradient(), TaoSetJacobianDesignRoutine(), TaoComputeJacobianDesign(), TaoSetStateDesignIS()
410a7e14dcfSSatish Balay @*/
41194ab13aaSBarry Smith PetscErrorCode TaoComputeJacobianDesign(Tao tao, Vec X, Mat J)
412a7e14dcfSSatish Balay {
413a7e14dcfSSatish Balay   PetscErrorCode ierr;
41487f595a5SBarry Smith 
415a7e14dcfSSatish Balay   PetscFunctionBegin;
416441846f8SBarry Smith   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
417a7e14dcfSSatish Balay   PetscValidHeaderSpecific(X, VEC_CLASSID,2);
418a7e14dcfSSatish Balay   PetscCheckSameComm(tao,1,X,2);
41987f595a5SBarry Smith   if (!tao->ops->computejacobiandesign) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Must call TaoSetJacobianDesign() first");
420a7e14dcfSSatish Balay   ++tao->njac_design;
4218860a134SJunchao Zhang   ierr = VecLockReadPush(X);CHKERRQ(ierr);
4220ebee16dSLisandro Dalcin   ierr = PetscLogEventBegin(TAO_JacobianEval,tao,X,J,NULL);CHKERRQ(ierr);
423441846f8SBarry Smith   PetscStackPush("Tao user Jacobian(design) function");
424a7e14dcfSSatish Balay   ierr = (*tao->ops->computejacobiandesign)(tao,X,J,tao->user_jac_designP);CHKERRQ(ierr);
425a7e14dcfSSatish Balay   PetscStackPop;
4260ebee16dSLisandro Dalcin   ierr = PetscLogEventEnd(TAO_JacobianEval,tao,X,J,NULL);CHKERRQ(ierr);
4278860a134SJunchao Zhang   ierr = VecLockReadPop(X);CHKERRQ(ierr);
428a7e14dcfSSatish Balay   PetscFunctionReturn(0);
429a7e14dcfSSatish Balay }
430a7e14dcfSSatish Balay 
431a7e14dcfSSatish Balay /*@C
432a7e14dcfSSatish Balay    TaoSetJacobianRoutine - Sets the function to compute the Jacobian as well as the location to store the matrix.
433a7e14dcfSSatish Balay 
434441846f8SBarry Smith    Logically collective on Tao
435a7e14dcfSSatish Balay 
436a7e14dcfSSatish Balay    Input Parameters:
437441846f8SBarry Smith +  tao  - the Tao context
438a7e14dcfSSatish Balay .  J    - Matrix used for the jacobian
439a7e14dcfSSatish Balay .  Jpre - Matrix that will be used operated on by preconditioner, can be same as J
440f4c1ad5cSStefano Zampini .  func - Jacobian evaluation routine
441a7e14dcfSSatish Balay -  ctx  - [optional] user-defined context for private data for the
4426c23d075SBarry Smith           Jacobian evaluation routine (may be NULL)
443a7e14dcfSSatish Balay 
444f4c1ad5cSStefano Zampini    Calling sequence of func:
445f4c1ad5cSStefano Zampini $    func(Tao tao,Vec x,Mat J,Mat Jpre,void *ctx);
446a7e14dcfSSatish Balay 
447441846f8SBarry Smith +  tao  - the Tao  context
448a7e14dcfSSatish Balay .  x    - input vector
449a7e14dcfSSatish Balay .  J    - Jacobian matrix
450f4c1ad5cSStefano Zampini .  Jpre - preconditioning matrix, usually the same as J
451a7e14dcfSSatish Balay -  ctx  - [optional] user-defined Jacobian context
452a7e14dcfSSatish Balay 
453a7e14dcfSSatish Balay    Level: intermediate
454a7e14dcfSSatish Balay @*/
455ffad9901SBarry Smith PetscErrorCode TaoSetJacobianRoutine(Tao tao, Mat J, Mat Jpre, PetscErrorCode (*func)(Tao, Vec, Mat, Mat, void*), void *ctx)
456a7e14dcfSSatish Balay {
457a7e14dcfSSatish Balay   PetscErrorCode ierr;
458f4c1ad5cSStefano Zampini 
459a7e14dcfSSatish Balay   PetscFunctionBegin;
460441846f8SBarry Smith   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
461a7e14dcfSSatish Balay   if (J) {
462a7e14dcfSSatish Balay     PetscValidHeaderSpecific(J,MAT_CLASSID,2);
463a7e14dcfSSatish Balay     PetscCheckSameComm(tao,1,J,2);
464a7e14dcfSSatish Balay   }
465a7e14dcfSSatish Balay   if (Jpre) {
466a7e14dcfSSatish Balay     PetscValidHeaderSpecific(Jpre,MAT_CLASSID,3);
467a7e14dcfSSatish Balay     PetscCheckSameComm(tao,1,Jpre,3);
468a7e14dcfSSatish Balay   }
469a7e14dcfSSatish Balay   if (ctx) {
470a7e14dcfSSatish Balay     tao->user_jacP = ctx;
471a7e14dcfSSatish Balay   }
472a7e14dcfSSatish Balay   if (func) {
473a7e14dcfSSatish Balay     tao->ops->computejacobian = func;
474a7e14dcfSSatish Balay   }
475a7e14dcfSSatish Balay   if (J) {
476a7e14dcfSSatish Balay     ierr = PetscObjectReference((PetscObject)J);CHKERRQ(ierr);
47745cf516eSBarry Smith     ierr = MatDestroy(&tao->jacobian);CHKERRQ(ierr);
478a7e14dcfSSatish Balay     tao->jacobian = J;
479a7e14dcfSSatish Balay   }
480a7e14dcfSSatish Balay   if (Jpre) {
481a7e14dcfSSatish Balay     ierr = PetscObjectReference((PetscObject)Jpre);CHKERRQ(ierr);
48245cf516eSBarry Smith     ierr = MatDestroy(&tao->jacobian_pre);CHKERRQ(ierr);
483a7e14dcfSSatish Balay     tao->jacobian_pre=Jpre;
484a7e14dcfSSatish Balay   }
485a7e14dcfSSatish Balay   PetscFunctionReturn(0);
486a7e14dcfSSatish Balay }
487a7e14dcfSSatish Balay 
488a7e14dcfSSatish Balay /*@C
4894ffbe8acSAlp Dener    TaoSetJacobianResidualRoutine - Sets the function to compute the least-squares residual Jacobian as well as the
4904a48860cSAlp Dener    location to store the matrix.
4914a48860cSAlp Dener 
4924a48860cSAlp Dener    Logically collective on Tao
4934a48860cSAlp Dener 
4944a48860cSAlp Dener    Input Parameters:
4954a48860cSAlp Dener +  tao  - the Tao context
4964a48860cSAlp Dener .  J    - Matrix used for the jacobian
4974a48860cSAlp Dener .  Jpre - Matrix that will be used operated on by preconditioner, can be same as J
4984a48860cSAlp Dener .  func - Jacobian evaluation routine
4994a48860cSAlp Dener -  ctx  - [optional] user-defined context for private data for the
5004a48860cSAlp Dener           Jacobian evaluation routine (may be NULL)
5014a48860cSAlp Dener 
5024a48860cSAlp Dener    Calling sequence of func:
5034a48860cSAlp Dener $    func(Tao tao,Vec x,Mat J,Mat Jpre,void *ctx);
5044a48860cSAlp Dener 
5054a48860cSAlp Dener +  tao  - the Tao  context
5064a48860cSAlp Dener .  x    - input vector
5074a48860cSAlp Dener .  J    - Jacobian matrix
5084a48860cSAlp Dener .  Jpre - preconditioning matrix, usually the same as J
5094a48860cSAlp Dener -  ctx  - [optional] user-defined Jacobian context
5104a48860cSAlp Dener 
5114a48860cSAlp Dener    Level: intermediate
5124a48860cSAlp Dener @*/
5134ffbe8acSAlp Dener PetscErrorCode TaoSetJacobianResidualRoutine(Tao tao, Mat J, Mat Jpre, PetscErrorCode (*func)(Tao, Vec, Mat, Mat, void*), void *ctx)
5144a48860cSAlp Dener {
5154a48860cSAlp Dener   PetscErrorCode ierr;
5164a48860cSAlp Dener 
5174a48860cSAlp Dener   PetscFunctionBegin;
5184a48860cSAlp Dener   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
5194a48860cSAlp Dener   if (J) {
5204a48860cSAlp Dener     PetscValidHeaderSpecific(J,MAT_CLASSID,2);
5214a48860cSAlp Dener     PetscCheckSameComm(tao,1,J,2);
5224a48860cSAlp Dener   }
5234a48860cSAlp Dener   if (Jpre) {
5244a48860cSAlp Dener     PetscValidHeaderSpecific(Jpre,MAT_CLASSID,3);
5254a48860cSAlp Dener     PetscCheckSameComm(tao,1,Jpre,3);
5264a48860cSAlp Dener   }
5274a48860cSAlp Dener   if (ctx) {
5284a48860cSAlp Dener     tao->user_lsjacP = ctx;
5294a48860cSAlp Dener   }
5304a48860cSAlp Dener   if (func) {
5314a48860cSAlp Dener     tao->ops->computeresidualjacobian = func;
5324a48860cSAlp Dener   }
5334a48860cSAlp Dener   if (J) {
5344a48860cSAlp Dener     ierr = PetscObjectReference((PetscObject)J);CHKERRQ(ierr);
5354a48860cSAlp Dener     ierr = MatDestroy(&tao->ls_jac);CHKERRQ(ierr);
5364a48860cSAlp Dener     tao->ls_jac = J;
5374a48860cSAlp Dener   }
5384a48860cSAlp Dener   if (Jpre) {
5394a48860cSAlp Dener     ierr = PetscObjectReference((PetscObject)Jpre);CHKERRQ(ierr);
5404a48860cSAlp Dener     ierr = MatDestroy(&tao->ls_jac_pre);CHKERRQ(ierr);
5414a48860cSAlp Dener     tao->ls_jac_pre=Jpre;
5424a48860cSAlp Dener   }
5434a48860cSAlp Dener   PetscFunctionReturn(0);
5444a48860cSAlp Dener }
5454a48860cSAlp Dener 
5464a48860cSAlp Dener /*@C
547a7e14dcfSSatish Balay    TaoSetJacobianStateRoutine - Sets the function to compute the Jacobian
548a7e14dcfSSatish Balay    (and its inverse) of the constraint function with respect to the state variables.
549a7e14dcfSSatish Balay    Used only for pde-constrained optimization.
550a7e14dcfSSatish Balay 
551441846f8SBarry Smith    Logically collective on Tao
552a7e14dcfSSatish Balay 
553a7e14dcfSSatish Balay    Input Parameters:
554441846f8SBarry Smith +  tao  - the Tao context
555a7e14dcfSSatish Balay .  J    - Matrix used for the jacobian
5566c23d075SBarry Smith .  Jpre - Matrix that will be used operated on by PETSc preconditioner, can be same as J.  Only used if Jinv is NULL
5576c23d075SBarry 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.
558f4c1ad5cSStefano Zampini .  func - Jacobian evaluation routine
559a7e14dcfSSatish Balay -  ctx  - [optional] user-defined context for private data for the
5606c23d075SBarry Smith           Jacobian evaluation routine (may be NULL)
561a7e14dcfSSatish Balay 
562f4c1ad5cSStefano Zampini    Calling sequence of func:
563f4c1ad5cSStefano Zampini $    func(Tao tao,Vec x,Mat J,Mat Jpre,Mat Jinv,void *ctx);
564a7e14dcfSSatish Balay 
565441846f8SBarry Smith +  tao  - the Tao  context
566a7e14dcfSSatish Balay .  x    - input vector
567a7e14dcfSSatish Balay .  J    - Jacobian matrix
568a7e14dcfSSatish Balay .  Jpre - preconditioner matrix, usually the same as J
569a7e14dcfSSatish Balay .  Jinv - inverse of J
570a7e14dcfSSatish Balay -  ctx  - [optional] user-defined Jacobian context
571a7e14dcfSSatish Balay 
572a7e14dcfSSatish Balay    Level: intermediate
573f4c1ad5cSStefano Zampini .seealso: TaoComputeJacobianState(), TaoSetJacobianDesignRoutine(), TaoSetStateDesignIS()
574a7e14dcfSSatish Balay @*/
575ffad9901SBarry Smith PetscErrorCode TaoSetJacobianStateRoutine(Tao tao, Mat J, Mat Jpre, Mat Jinv, PetscErrorCode (*func)(Tao, Vec, Mat, Mat, Mat, void*), void *ctx)
576a7e14dcfSSatish Balay {
577a7e14dcfSSatish Balay   PetscErrorCode ierr;
578f4c1ad5cSStefano Zampini 
579a7e14dcfSSatish Balay   PetscFunctionBegin;
580441846f8SBarry Smith   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
581a7e14dcfSSatish Balay   if (J) {
582a7e14dcfSSatish Balay     PetscValidHeaderSpecific(J,MAT_CLASSID,2);
583a7e14dcfSSatish Balay     PetscCheckSameComm(tao,1,J,2);
584a7e14dcfSSatish Balay   }
585a7e14dcfSSatish Balay   if (Jpre) {
586a7e14dcfSSatish Balay     PetscValidHeaderSpecific(Jpre,MAT_CLASSID,3);
587a7e14dcfSSatish Balay     PetscCheckSameComm(tao,1,Jpre,3);
588a7e14dcfSSatish Balay   }
589a7e14dcfSSatish Balay   if (Jinv) {
590a7e14dcfSSatish Balay     PetscValidHeaderSpecific(Jinv,MAT_CLASSID,4);
591a7e14dcfSSatish Balay     PetscCheckSameComm(tao,1,Jinv,4);
592a7e14dcfSSatish Balay   }
593a7e14dcfSSatish Balay   if (ctx) {
594a7e14dcfSSatish Balay     tao->user_jac_stateP = ctx;
595a7e14dcfSSatish Balay   }
596a7e14dcfSSatish Balay   if (func) {
597a7e14dcfSSatish Balay     tao->ops->computejacobianstate = func;
598a7e14dcfSSatish Balay   }
599a7e14dcfSSatish Balay   if (J) {
600a7e14dcfSSatish Balay     ierr = PetscObjectReference((PetscObject)J);CHKERRQ(ierr);
60145cf516eSBarry Smith     ierr = MatDestroy(&tao->jacobian_state);CHKERRQ(ierr);
602a7e14dcfSSatish Balay     tao->jacobian_state = J;
603a7e14dcfSSatish Balay   }
604a7e14dcfSSatish Balay   if (Jpre) {
605a7e14dcfSSatish Balay     ierr = PetscObjectReference((PetscObject)Jpre);CHKERRQ(ierr);
60645cf516eSBarry Smith     ierr = MatDestroy(&tao->jacobian_state_pre);CHKERRQ(ierr);
607a7e14dcfSSatish Balay     tao->jacobian_state_pre=Jpre;
608a7e14dcfSSatish Balay   }
609a7e14dcfSSatish Balay   if (Jinv) {
610a7e14dcfSSatish Balay     ierr = PetscObjectReference((PetscObject)Jinv);CHKERRQ(ierr);
61145cf516eSBarry Smith     ierr = MatDestroy(&tao->jacobian_state_inv);CHKERRQ(ierr);
612a7e14dcfSSatish Balay     tao->jacobian_state_inv=Jinv;
613a7e14dcfSSatish Balay   }
614a7e14dcfSSatish Balay   PetscFunctionReturn(0);
615a7e14dcfSSatish Balay }
616a7e14dcfSSatish Balay 
617a7e14dcfSSatish Balay /*@C
618a7e14dcfSSatish Balay    TaoSetJacobianDesignRoutine - Sets the function to compute the Jacobian of
619a7e14dcfSSatish Balay    the constraint function with respect to the design variables.  Used only for
620a7e14dcfSSatish Balay    pde-constrained optimization.
621a7e14dcfSSatish Balay 
622441846f8SBarry Smith    Logically collective on Tao
623a7e14dcfSSatish Balay 
624a7e14dcfSSatish Balay    Input Parameters:
625441846f8SBarry Smith +  tao  - the Tao context
626a7e14dcfSSatish Balay .  J    - Matrix used for the jacobian
627f4c1ad5cSStefano Zampini .  func - Jacobian evaluation routine
628a7e14dcfSSatish Balay -  ctx  - [optional] user-defined context for private data for the
6296c23d075SBarry Smith           Jacobian evaluation routine (may be NULL)
630a7e14dcfSSatish Balay 
631f4c1ad5cSStefano Zampini    Calling sequence of func:
632f4c1ad5cSStefano Zampini $    func(Tao tao,Vec x,Mat J,void *ctx);
633a7e14dcfSSatish Balay 
634441846f8SBarry Smith +  tao - the Tao  context
635a7e14dcfSSatish Balay .  x   - input vector
636a7e14dcfSSatish Balay .  J   - Jacobian matrix
637a7e14dcfSSatish Balay -  ctx - [optional] user-defined Jacobian context
638a7e14dcfSSatish Balay 
639a7e14dcfSSatish Balay    Level: intermediate
640f4c1ad5cSStefano Zampini 
641a7e14dcfSSatish Balay .seealso: TaoComputeJacobianDesign(), TaoSetJacobianStateRoutine(), TaoSetStateDesignIS()
642a7e14dcfSSatish Balay @*/
64394ab13aaSBarry Smith PetscErrorCode TaoSetJacobianDesignRoutine(Tao tao, Mat J, PetscErrorCode (*func)(Tao, Vec, Mat, void*), void *ctx)
644a7e14dcfSSatish Balay {
645a7e14dcfSSatish Balay   PetscErrorCode ierr;
64645cf516eSBarry Smith 
647a7e14dcfSSatish Balay   PetscFunctionBegin;
648441846f8SBarry Smith   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
649a7e14dcfSSatish Balay   if (J) {
650a7e14dcfSSatish Balay     PetscValidHeaderSpecific(J,MAT_CLASSID,2);
651a7e14dcfSSatish Balay     PetscCheckSameComm(tao,1,J,2);
652a7e14dcfSSatish Balay   }
653a7e14dcfSSatish Balay   if (ctx) {
654a7e14dcfSSatish Balay     tao->user_jac_designP = ctx;
655a7e14dcfSSatish Balay   }
656a7e14dcfSSatish Balay   if (func) {
657a7e14dcfSSatish Balay     tao->ops->computejacobiandesign = func;
658a7e14dcfSSatish Balay   }
659a7e14dcfSSatish Balay   if (J) {
660a7e14dcfSSatish Balay     ierr = PetscObjectReference((PetscObject)J);CHKERRQ(ierr);
66145cf516eSBarry Smith     ierr = MatDestroy(&tao->jacobian_design);CHKERRQ(ierr);
662a7e14dcfSSatish Balay     tao->jacobian_design = J;
663a7e14dcfSSatish Balay   }
664a7e14dcfSSatish Balay   PetscFunctionReturn(0);
665a7e14dcfSSatish Balay }
666a7e14dcfSSatish Balay 
667a7e14dcfSSatish Balay /*@
668441846f8SBarry Smith    TaoSetStateDesignIS - Indicate to the Tao which variables in the
669a7e14dcfSSatish Balay    solution vector are state variables and which are design.  Only applies to
670a7e14dcfSSatish Balay    pde-constrained optimization.
671a7e14dcfSSatish Balay 
672441846f8SBarry Smith    Logically Collective on Tao
673a7e14dcfSSatish Balay 
674a7e14dcfSSatish Balay    Input Parameters:
675441846f8SBarry Smith +  tao  - The Tao context
676a7e14dcfSSatish Balay .  s_is - the index set corresponding to the state variables
677a7e14dcfSSatish Balay -  d_is - the index set corresponding to the design variables
678a7e14dcfSSatish Balay 
679a7e14dcfSSatish Balay    Level: intermediate
680a7e14dcfSSatish Balay 
681a7e14dcfSSatish Balay .seealso: TaoSetJacobianStateRoutine(), TaoSetJacobianDesignRoutine()
682a7e14dcfSSatish Balay @*/
683441846f8SBarry Smith PetscErrorCode TaoSetStateDesignIS(Tao tao, IS s_is, IS d_is)
684a7e14dcfSSatish Balay {
685a7e14dcfSSatish Balay   PetscErrorCode ierr;
68645cf516eSBarry Smith 
68745cf516eSBarry Smith   PetscFunctionBegin;
68845cf516eSBarry Smith   ierr = PetscObjectReference((PetscObject)s_is);CHKERRQ(ierr);
68945cf516eSBarry Smith   ierr = ISDestroy(&tao->state_is);CHKERRQ(ierr);
690a7e14dcfSSatish Balay   tao->state_is = s_is;
69145cf516eSBarry Smith   ierr = PetscObjectReference((PetscObject)(d_is));CHKERRQ(ierr);
69245cf516eSBarry Smith   ierr = ISDestroy(&tao->design_is);CHKERRQ(ierr);
693a7e14dcfSSatish Balay   tao->design_is = d_is;
694a7e14dcfSSatish Balay   PetscFunctionReturn(0);
695a7e14dcfSSatish Balay }
696a7e14dcfSSatish Balay 
697a7e14dcfSSatish Balay /*@C
698a7e14dcfSSatish Balay    TaoComputeJacobianEquality - Computes the Jacobian matrix that has been
699a7e14dcfSSatish Balay    set with TaoSetJacobianEqualityRoutine().
700a7e14dcfSSatish Balay 
701441846f8SBarry Smith    Collective on Tao
702a7e14dcfSSatish Balay 
703a7e14dcfSSatish Balay    Input Parameters:
704f4c1ad5cSStefano Zampini +  tao - the Tao solver context
705f4c1ad5cSStefano Zampini -  X   - input vector
706a7e14dcfSSatish Balay 
707a7e14dcfSSatish Balay    Output Parameters:
708f4c1ad5cSStefano Zampini +  J    - Jacobian matrix
709f4c1ad5cSStefano Zampini -  Jpre - Preconditioning matrix
710a7e14dcfSSatish Balay 
711a7e14dcfSSatish Balay    Notes:
712a7e14dcfSSatish Balay    Most users should not need to explicitly call this routine, as it
713a7e14dcfSSatish Balay    is used internally within the minimization solvers.
714a7e14dcfSSatish Balay 
715a7e14dcfSSatish Balay    Level: developer
716a7e14dcfSSatish Balay 
717a7e14dcfSSatish Balay .seealso:  TaoComputeObjective(), TaoComputeObjectiveAndGradient(), TaoSetJacobianStateRoutine(), TaoComputeJacobianDesign(), TaoSetStateDesignIS()
718a7e14dcfSSatish Balay @*/
719ffad9901SBarry Smith PetscErrorCode TaoComputeJacobianEquality(Tao tao, Vec X, Mat J, Mat Jpre)
720a7e14dcfSSatish Balay {
721a7e14dcfSSatish Balay   PetscErrorCode ierr;
72245cf516eSBarry Smith 
723a7e14dcfSSatish Balay   PetscFunctionBegin;
724441846f8SBarry Smith   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
725a7e14dcfSSatish Balay   PetscValidHeaderSpecific(X, VEC_CLASSID,2);
726a7e14dcfSSatish Balay   PetscCheckSameComm(tao,1,X,2);
72787f595a5SBarry Smith   if (!tao->ops->computejacobianequality) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Must call TaoSetJacobianEquality() first");
728a7e14dcfSSatish Balay   ++tao->njac_equality;
7298860a134SJunchao Zhang   ierr = VecLockReadPush(X);CHKERRQ(ierr);
7300ebee16dSLisandro Dalcin   ierr = PetscLogEventBegin(TAO_JacobianEval,tao,X,J,Jpre);CHKERRQ(ierr);
731441846f8SBarry Smith   PetscStackPush("Tao user Jacobian(equality) function");
732ffad9901SBarry Smith   ierr = (*tao->ops->computejacobianequality)(tao,X,J,Jpre,tao->user_jac_equalityP);CHKERRQ(ierr);
733a7e14dcfSSatish Balay   PetscStackPop;
7340ebee16dSLisandro Dalcin   ierr = PetscLogEventEnd(TAO_JacobianEval,tao,X,J,Jpre);CHKERRQ(ierr);
7358860a134SJunchao Zhang   ierr = VecLockReadPop(X);CHKERRQ(ierr);
736a7e14dcfSSatish Balay   PetscFunctionReturn(0);
737a7e14dcfSSatish Balay }
738a7e14dcfSSatish Balay 
739a7e14dcfSSatish Balay /*@C
740a7e14dcfSSatish Balay    TaoComputeJacobianInequality - Computes the Jacobian matrix that has been
741a7e14dcfSSatish Balay    set with TaoSetJacobianInequalityRoutine().
742a7e14dcfSSatish Balay 
743441846f8SBarry Smith    Collective on Tao
744a7e14dcfSSatish Balay 
745a7e14dcfSSatish Balay    Input Parameters:
746f4c1ad5cSStefano Zampini +  tao - the Tao solver context
747f4c1ad5cSStefano Zampini -  X   - input vector
748a7e14dcfSSatish Balay 
749a7e14dcfSSatish Balay    Output Parameters:
750f4c1ad5cSStefano Zampini +  J    - Jacobian matrix
751f4c1ad5cSStefano Zampini -  Jpre - Preconditioning matrix
752a7e14dcfSSatish Balay 
753a7e14dcfSSatish Balay    Notes:
754a7e14dcfSSatish Balay    Most users should not need to explicitly call this routine, as it
755a7e14dcfSSatish Balay    is used internally within the minimization solvers.
756a7e14dcfSSatish Balay 
757a7e14dcfSSatish Balay    Level: developer
758a7e14dcfSSatish Balay 
759a7e14dcfSSatish Balay .seealso:  TaoComputeObjective(), TaoComputeObjectiveAndGradient(), TaoSetJacobianStateRoutine(), TaoComputeJacobianDesign(), TaoSetStateDesignIS()
760a7e14dcfSSatish Balay @*/
761ffad9901SBarry Smith PetscErrorCode TaoComputeJacobianInequality(Tao tao, Vec X, Mat J, Mat Jpre)
762a7e14dcfSSatish Balay {
763a7e14dcfSSatish Balay   PetscErrorCode ierr;
76487f595a5SBarry Smith 
765a7e14dcfSSatish Balay   PetscFunctionBegin;
766441846f8SBarry Smith   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
767a7e14dcfSSatish Balay   PetscValidHeaderSpecific(X, VEC_CLASSID,2);
768a7e14dcfSSatish Balay   PetscCheckSameComm(tao,1,X,2);
76987f595a5SBarry Smith   if (!tao->ops->computejacobianinequality) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Must call TaoSetJacobianInequality() first");
770a7e14dcfSSatish Balay   ++tao->njac_inequality;
7718860a134SJunchao Zhang   ierr = VecLockReadPush(X);CHKERRQ(ierr);
7720ebee16dSLisandro Dalcin   ierr = PetscLogEventBegin(TAO_JacobianEval,tao,X,J,Jpre);CHKERRQ(ierr);
773441846f8SBarry Smith   PetscStackPush("Tao user Jacobian(inequality) function");
774ffad9901SBarry Smith   ierr = (*tao->ops->computejacobianinequality)(tao,X,J,Jpre,tao->user_jac_inequalityP);CHKERRQ(ierr);
775a7e14dcfSSatish Balay   PetscStackPop;
7760ebee16dSLisandro Dalcin   ierr = PetscLogEventEnd(TAO_JacobianEval,tao,X,J,Jpre);CHKERRQ(ierr);
7778860a134SJunchao Zhang   ierr = VecLockReadPop(X);CHKERRQ(ierr);
778a7e14dcfSSatish Balay   PetscFunctionReturn(0);
779a7e14dcfSSatish Balay }
780a7e14dcfSSatish Balay 
781a7e14dcfSSatish Balay /*@C
782a7e14dcfSSatish Balay    TaoSetJacobianEqualityRoutine - Sets the function to compute the Jacobian
783a7e14dcfSSatish Balay    (and its inverse) of the constraint function with respect to the equality variables.
784a7e14dcfSSatish Balay    Used only for pde-constrained optimization.
785a7e14dcfSSatish Balay 
786441846f8SBarry Smith    Logically collective on Tao
787a7e14dcfSSatish Balay 
788a7e14dcfSSatish Balay    Input Parameters:
789441846f8SBarry Smith +  tao  - the Tao context
790a7e14dcfSSatish Balay .  J    - Matrix used for the jacobian
791a7e14dcfSSatish Balay .  Jpre - Matrix that will be used operated on by PETSc preconditioner, can be same as J.
792f4c1ad5cSStefano Zampini .  func - Jacobian evaluation routine
793a7e14dcfSSatish Balay -  ctx  - [optional] user-defined context for private data for the
7946c23d075SBarry Smith           Jacobian evaluation routine (may be NULL)
795a7e14dcfSSatish Balay 
796f4c1ad5cSStefano Zampini    Calling sequence of func:
797f4c1ad5cSStefano Zampini $    func(Tao tao,Vec x,Mat J,Mat Jpre,void *ctx);
798a7e14dcfSSatish Balay 
799441846f8SBarry Smith +  tao  - the Tao  context
800a7e14dcfSSatish Balay .  x    - input vector
801a7e14dcfSSatish Balay .  J    - Jacobian matrix
802a7e14dcfSSatish Balay .  Jpre - preconditioner matrix, usually the same as J
803a7e14dcfSSatish Balay -  ctx  - [optional] user-defined Jacobian context
804a7e14dcfSSatish Balay 
805a7e14dcfSSatish Balay    Level: intermediate
806f4c1ad5cSStefano Zampini 
807f4c1ad5cSStefano Zampini .seealso: TaoComputeJacobianEquality(), TaoSetJacobianDesignRoutine(), TaoSetEqualityDesignIS()
808a7e14dcfSSatish Balay @*/
809ffad9901SBarry Smith PetscErrorCode TaoSetJacobianEqualityRoutine(Tao tao, Mat J, Mat Jpre, PetscErrorCode (*func)(Tao, Vec, Mat, Mat,void*), void *ctx)
810a7e14dcfSSatish Balay {
811a7e14dcfSSatish Balay   PetscErrorCode ierr;
81245cf516eSBarry Smith 
813a7e14dcfSSatish Balay   PetscFunctionBegin;
814441846f8SBarry Smith   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
815a7e14dcfSSatish Balay   if (J) {
816a7e14dcfSSatish Balay     PetscValidHeaderSpecific(J,MAT_CLASSID,2);
817a7e14dcfSSatish Balay     PetscCheckSameComm(tao,1,J,2);
818a7e14dcfSSatish Balay   }
819a7e14dcfSSatish Balay   if (Jpre) {
820a7e14dcfSSatish Balay     PetscValidHeaderSpecific(Jpre,MAT_CLASSID,3);
821a7e14dcfSSatish Balay     PetscCheckSameComm(tao,1,Jpre,3);
822a7e14dcfSSatish Balay   }
823a7e14dcfSSatish Balay   if (ctx) {
824a7e14dcfSSatish Balay     tao->user_jac_equalityP = ctx;
825a7e14dcfSSatish Balay   }
826a7e14dcfSSatish Balay   if (func) {
827a7e14dcfSSatish Balay     tao->ops->computejacobianequality = func;
828a7e14dcfSSatish Balay   }
829a7e14dcfSSatish Balay   if (J) {
830a7e14dcfSSatish Balay     ierr = PetscObjectReference((PetscObject)J);CHKERRQ(ierr);
83145cf516eSBarry Smith     ierr = MatDestroy(&tao->jacobian_equality);CHKERRQ(ierr);
832a7e14dcfSSatish Balay     tao->jacobian_equality = J;
833a7e14dcfSSatish Balay   }
834a7e14dcfSSatish Balay   if (Jpre) {
835a7e14dcfSSatish Balay     ierr = PetscObjectReference((PetscObject)Jpre);CHKERRQ(ierr);
83645cf516eSBarry Smith     ierr = MatDestroy(&tao->jacobian_equality_pre);CHKERRQ(ierr);
837a7e14dcfSSatish Balay     tao->jacobian_equality_pre=Jpre;
838a7e14dcfSSatish Balay   }
839a7e14dcfSSatish Balay   PetscFunctionReturn(0);
840a7e14dcfSSatish Balay }
841a7e14dcfSSatish Balay 
842a7e14dcfSSatish Balay /*@C
843a7e14dcfSSatish Balay    TaoSetJacobianInequalityRoutine - Sets the function to compute the Jacobian
844a7e14dcfSSatish Balay    (and its inverse) of the constraint function with respect to the inequality variables.
845a7e14dcfSSatish Balay    Used only for pde-constrained optimization.
846a7e14dcfSSatish Balay 
847441846f8SBarry Smith    Logically collective on Tao
848a7e14dcfSSatish Balay 
849a7e14dcfSSatish Balay    Input Parameters:
850441846f8SBarry Smith +  tao  - the Tao context
851a7e14dcfSSatish Balay .  J    - Matrix used for the jacobian
852a7e14dcfSSatish Balay .  Jpre - Matrix that will be used operated on by PETSc preconditioner, can be same as J.
853f4c1ad5cSStefano Zampini .  func - Jacobian evaluation routine
854a7e14dcfSSatish Balay -  ctx  - [optional] user-defined context for private data for the
8556c23d075SBarry Smith           Jacobian evaluation routine (may be NULL)
856a7e14dcfSSatish Balay 
857f4c1ad5cSStefano Zampini    Calling sequence of func:
858f4c1ad5cSStefano Zampini $    func(Tao tao,Vec x,Mat J,Mat Jpre,void *ctx);
859a7e14dcfSSatish Balay 
860441846f8SBarry Smith +  tao  - the Tao  context
861a7e14dcfSSatish Balay .  x    - input vector
862a7e14dcfSSatish Balay .  J    - Jacobian matrix
863a7e14dcfSSatish Balay .  Jpre - preconditioner matrix, usually the same as J
864a7e14dcfSSatish Balay -  ctx  - [optional] user-defined Jacobian context
865a7e14dcfSSatish Balay 
866a7e14dcfSSatish Balay    Level: intermediate
867f4c1ad5cSStefano Zampini 
868f4c1ad5cSStefano Zampini .seealso: TaoComputeJacobianInequality(), TaoSetJacobianDesignRoutine(), TaoSetInequalityDesignIS()
869a7e14dcfSSatish Balay @*/
870ffad9901SBarry Smith PetscErrorCode TaoSetJacobianInequalityRoutine(Tao tao, Mat J, Mat Jpre, PetscErrorCode (*func)(Tao, Vec, Mat, Mat,void*), void *ctx)
871a7e14dcfSSatish Balay {
872a7e14dcfSSatish Balay   PetscErrorCode ierr;
873f4c1ad5cSStefano Zampini 
874a7e14dcfSSatish Balay   PetscFunctionBegin;
875441846f8SBarry Smith   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
876a7e14dcfSSatish Balay   if (J) {
877a7e14dcfSSatish Balay     PetscValidHeaderSpecific(J,MAT_CLASSID,2);
878a7e14dcfSSatish Balay     PetscCheckSameComm(tao,1,J,2);
879a7e14dcfSSatish Balay   }
880a7e14dcfSSatish Balay   if (Jpre) {
881a7e14dcfSSatish Balay     PetscValidHeaderSpecific(Jpre,MAT_CLASSID,3);
882a7e14dcfSSatish Balay     PetscCheckSameComm(tao,1,Jpre,3);
883a7e14dcfSSatish Balay   }
884a7e14dcfSSatish Balay   if (ctx) {
885a7e14dcfSSatish Balay     tao->user_jac_inequalityP = ctx;
886a7e14dcfSSatish Balay   }
887a7e14dcfSSatish Balay   if (func) {
888a7e14dcfSSatish Balay     tao->ops->computejacobianinequality = func;
889a7e14dcfSSatish Balay   }
890a7e14dcfSSatish Balay   if (J) {
891a7e14dcfSSatish Balay     ierr = PetscObjectReference((PetscObject)J);CHKERRQ(ierr);
89245cf516eSBarry Smith     ierr = MatDestroy(&tao->jacobian_inequality);CHKERRQ(ierr);
893a7e14dcfSSatish Balay     tao->jacobian_inequality = J;
894a7e14dcfSSatish Balay   }
895a7e14dcfSSatish Balay   if (Jpre) {
896a7e14dcfSSatish Balay     ierr = PetscObjectReference((PetscObject)Jpre);CHKERRQ(ierr);
89745cf516eSBarry Smith     ierr = MatDestroy(&tao->jacobian_inequality_pre);CHKERRQ(ierr);
898a7e14dcfSSatish Balay     tao->jacobian_inequality_pre=Jpre;
899a7e14dcfSSatish Balay   }
900a7e14dcfSSatish Balay   PetscFunctionReturn(0);
901a7e14dcfSSatish Balay }
902