xref: /petsc/src/tao/interface/taosolver_hj.c (revision 65ba42b6ab3ec006bc8f22d89b4121d18fc8be1b)
1af0996ceSBarry Smith #include <petsc/private/taoimpl.h> /*I "petsctao.h" I*/
2a7e14dcfSSatish Balay 
3a7e14dcfSSatish Balay /*@C
4a82e8c82SStefano Zampini    TaoSetHessian - Sets the function to compute the Hessian as well as the location to store the matrix.
5a7e14dcfSSatish Balay 
6*65ba42b6SBarry 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
26a82e8c82SStefano Zampini 
27*65ba42b6SBarry Smith .seealso: `Tao`, `TaoTypes`, `TaoSetObjective()`, `TaoSetGradient()`, `TaoSetObjectiveAndGradient()`, `TaoGetHessian()`
28a7e14dcfSSatish Balay @*/
29a82e8c82SStefano Zampini PetscErrorCode TaoSetHessian(Tao tao, Mat H, Mat Hpre, PetscErrorCode (*func)(Tao, Vec, Mat, Mat, void*), void *ctx)
30a7e14dcfSSatish Balay {
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   }
41a82e8c82SStefano Zampini   if (ctx) tao->user_hessP = ctx;
42a82e8c82SStefano Zampini   if (func) tao->ops->computehessian = func;
43a7e14dcfSSatish Balay   if (H) {
449566063dSJacob Faibussowitsch     PetscCall(PetscObjectReference((PetscObject)H));
459566063dSJacob Faibussowitsch     PetscCall(MatDestroy(&tao->hessian));
46a7e14dcfSSatish Balay     tao->hessian = H;
47a7e14dcfSSatish Balay   }
48a7e14dcfSSatish Balay   if (Hpre) {
499566063dSJacob Faibussowitsch     PetscCall(PetscObjectReference((PetscObject)Hpre));
509566063dSJacob Faibussowitsch     PetscCall(MatDestroy(&tao->hessian_pre));
51a7e14dcfSSatish Balay     tao->hessian_pre = Hpre;
52a7e14dcfSSatish Balay   }
53a7e14dcfSSatish Balay   PetscFunctionReturn(0);
54a7e14dcfSSatish Balay }
55a7e14dcfSSatish Balay 
56a82e8c82SStefano Zampini /*@C
57a82e8c82SStefano Zampini    TaoGetHessian - Gets the function to compute the Hessian as well as the location to store the matrix.
58a82e8c82SStefano Zampini 
59a82e8c82SStefano Zampini    Not collective
60a82e8c82SStefano Zampini 
61a82e8c82SStefano Zampini    Input Parameter:
62a82e8c82SStefano Zampini .  tao  - the Tao context
63a82e8c82SStefano Zampini 
64a82e8c82SStefano Zampini    OutputParameters:
65a82e8c82SStefano Zampini +  H    - Matrix used for the hessian
66a82e8c82SStefano Zampini .  Hpre - Matrix that will be used operated on by preconditioner, can be the same as H
67a82e8c82SStefano Zampini .  func - Hessian evaluation routine
68a82e8c82SStefano Zampini -  ctx  - user-defined context for private data for the Hessian evaluation routine
69a82e8c82SStefano Zampini 
70a82e8c82SStefano Zampini    Calling sequence of func:
71a82e8c82SStefano Zampini $    func(Tao tao,Vec x,Mat H,Mat Hpre,void *ctx);
72a82e8c82SStefano Zampini 
73a82e8c82SStefano Zampini +  tao  - the Tao  context
74a82e8c82SStefano Zampini .  x    - input vector
75a82e8c82SStefano Zampini .  H    - Hessian matrix
76a82e8c82SStefano Zampini .  Hpre - preconditioner matrix, usually the same as H
77a82e8c82SStefano Zampini -  ctx  - [optional] user-defined Hessian context
78a82e8c82SStefano Zampini 
79a82e8c82SStefano Zampini    Level: beginner
80a82e8c82SStefano Zampini 
81*65ba42b6SBarry Smith .seealso: `Tao`, TaoType`, `TaoGetObjective()`, `TaoGetGradient()`, `TaoGetObjectiveAndGradient()`, `TaoSetHessian()`
82a82e8c82SStefano Zampini @*/
83a82e8c82SStefano Zampini PetscErrorCode TaoGetHessian(Tao tao, Mat *H, Mat *Hpre, PetscErrorCode (**func)(Tao, Vec, Mat, Mat, void*), void **ctx)
84a82e8c82SStefano Zampini {
85a82e8c82SStefano Zampini   PetscFunctionBegin;
86a82e8c82SStefano Zampini   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
87a82e8c82SStefano Zampini   if (H) *H = tao->hessian;
88a82e8c82SStefano Zampini   if (Hpre) *Hpre = tao->hessian_pre;
89a82e8c82SStefano Zampini   if (ctx) *ctx = tao->user_hessP;
90a82e8c82SStefano Zampini   if (func) *func = tao->ops->computehessian;
91a82e8c82SStefano Zampini   PetscFunctionReturn(0);
92a82e8c82SStefano Zampini }
93a82e8c82SStefano Zampini 
9409baa881SHong Zhang PetscErrorCode TaoTestHessian(Tao tao)
9509baa881SHong Zhang {
9609baa881SHong Zhang   Mat               A,B,C,D,hessian;
9709baa881SHong Zhang   Vec               x = tao->solution;
9809baa881SHong Zhang   PetscReal         nrm,gnorm;
9909baa881SHong Zhang   PetscReal         threshold = 1.e-5;
10009baa881SHong Zhang   PetscInt          m,n,M,N;
10109baa881SHong Zhang   PetscBool         complete_print = PETSC_FALSE,test = PETSC_FALSE,flg;
102f49d1c87SHong Zhang   PetscViewer       viewer,mviewer;
10309baa881SHong Zhang   MPI_Comm          comm;
10409baa881SHong Zhang   PetscInt          tabs;
10509baa881SHong Zhang   static PetscBool  directionsprinted = PETSC_FALSE;
106f49d1c87SHong Zhang   PetscViewerFormat format;
10709baa881SHong Zhang 
10809baa881SHong Zhang   PetscFunctionBegin;
109d0609cedSBarry Smith   PetscObjectOptionsBegin((PetscObject)tao);
1109566063dSJacob Faibussowitsch   PetscCall(PetscOptionsName("-tao_test_hessian","Compare hand-coded and finite difference Hessians","None",&test));
1119566063dSJacob Faibussowitsch   PetscCall(PetscOptionsReal("-tao_test_hessian", "Threshold for element difference between hand-coded and finite difference being meaningful","None",threshold,&threshold,NULL));
1129566063dSJacob Faibussowitsch   PetscCall(PetscOptionsViewer("-tao_test_hessian_view","View difference between hand-coded and finite difference Hessians element entries","None",&mviewer,&format,&complete_print));
113d0609cedSBarry Smith   PetscOptionsEnd();
11409baa881SHong Zhang   if (!test) PetscFunctionReturn(0);
11509baa881SHong Zhang 
1169566063dSJacob Faibussowitsch   PetscCall(PetscObjectGetComm((PetscObject)tao,&comm));
1179566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIGetStdout(comm,&viewer));
1189566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIGetTab(viewer, &tabs));
1199566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIISetTab(viewer, ((PetscObject)tao)->tablevel));
1209566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPrintf(viewer,"  ---------- Testing Hessian -------------\n"));
12109baa881SHong Zhang   if (!complete_print && !directionsprinted) {
1229566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer,"  Run with -tao_test_hessian_view and optionally -tao_test_hessian <threshold> to show difference\n"));
1239566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer,"    of hand-coded and finite difference Hessian entries greater than <threshold>.\n"));
12409baa881SHong Zhang   }
12509baa881SHong Zhang   if (!directionsprinted) {
1269566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer,"  Testing hand-coded Hessian, if (for double precision runs) ||J - Jfd||_F/||J||_F is\n"));
1279566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer,"    O(1.e-8), the hand-coded Hessian is probably correct.\n"));
12809baa881SHong Zhang     directionsprinted = PETSC_TRUE;
12909baa881SHong Zhang   }
1301baa6e33SBarry Smith   if (complete_print) PetscCall(PetscViewerPushFormat(mviewer,format));
13109baa881SHong Zhang 
1329566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)tao->hessian,MATMFFD,&flg));
13309baa881SHong Zhang   if (!flg) hessian = tao->hessian;
13409baa881SHong Zhang   else hessian = tao->hessian_pre;
13509baa881SHong Zhang 
13609baa881SHong Zhang   while (hessian) {
1379566063dSJacob Faibussowitsch     PetscCall(PetscObjectBaseTypeCompareAny((PetscObject)hessian,&flg,MATSEQAIJ,MATMPIAIJ,MATSEQDENSE,MATMPIDENSE,MATSEQBAIJ,MATMPIBAIJ,MATSEQSBAIJ,MATMPIBAIJ,""));
13809baa881SHong Zhang     if (flg) {
13909baa881SHong Zhang       A    = hessian;
1409566063dSJacob Faibussowitsch       PetscCall(PetscObjectReference((PetscObject)A));
14109baa881SHong Zhang     } else {
1429566063dSJacob Faibussowitsch       PetscCall(MatComputeOperator(hessian,MATAIJ,&A));
14309baa881SHong Zhang     }
14409baa881SHong Zhang 
1459566063dSJacob Faibussowitsch     PetscCall(MatCreate(PetscObjectComm((PetscObject)A),&B));
1469566063dSJacob Faibussowitsch     PetscCall(MatGetSize(A,&M,&N));
1479566063dSJacob Faibussowitsch     PetscCall(MatGetLocalSize(A,&m,&n));
1489566063dSJacob Faibussowitsch     PetscCall(MatSetSizes(B,m,n,M,N));
1499566063dSJacob Faibussowitsch     PetscCall(MatSetType(B,((PetscObject)A)->type_name));
1509566063dSJacob Faibussowitsch     PetscCall(MatSetUp(B));
1519566063dSJacob Faibussowitsch     PetscCall(MatSetOption(B,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_FALSE));
15209baa881SHong Zhang 
1539566063dSJacob Faibussowitsch     PetscCall(TaoDefaultComputeHessian(tao,x,B,B,NULL));
15409baa881SHong Zhang 
1559566063dSJacob Faibussowitsch     PetscCall(MatDuplicate(B,MAT_COPY_VALUES,&D));
1569566063dSJacob Faibussowitsch     PetscCall(MatAYPX(D,-1.0,A,DIFFERENT_NONZERO_PATTERN));
1579566063dSJacob Faibussowitsch     PetscCall(MatNorm(D,NORM_FROBENIUS,&nrm));
1589566063dSJacob Faibussowitsch     PetscCall(MatNorm(A,NORM_FROBENIUS,&gnorm));
1599566063dSJacob Faibussowitsch     PetscCall(MatDestroy(&D));
16009baa881SHong Zhang     if (!gnorm) gnorm = 1; /* just in case */
1619566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer,"  ||H - Hfd||_F/||H||_F = %g, ||H - Hfd||_F = %g\n",(double)(nrm/gnorm),(double)nrm));
16209baa881SHong Zhang 
16309baa881SHong Zhang     if (complete_print) {
1649566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer,"  Hand-coded Hessian ----------\n"));
1659566063dSJacob Faibussowitsch       PetscCall(MatView(A,mviewer));
1669566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer,"  Finite difference Hessian ----------\n"));
1679566063dSJacob Faibussowitsch       PetscCall(MatView(B,mviewer));
16809baa881SHong Zhang     }
16909baa881SHong Zhang 
17009baa881SHong Zhang     if (complete_print) {
17109baa881SHong Zhang       PetscInt          Istart, Iend, *ccols, bncols, cncols, j, row;
17209baa881SHong Zhang       PetscScalar       *cvals;
17309baa881SHong Zhang       const PetscInt    *bcols;
17409baa881SHong Zhang       const PetscScalar *bvals;
17509baa881SHong Zhang 
1769566063dSJacob Faibussowitsch       PetscCall(MatAYPX(B,-1.0,A,DIFFERENT_NONZERO_PATTERN));
1779566063dSJacob Faibussowitsch       PetscCall(MatCreate(PetscObjectComm((PetscObject)A),&C));
1789566063dSJacob Faibussowitsch       PetscCall(MatSetSizes(C,m,n,M,N));
1799566063dSJacob Faibussowitsch       PetscCall(MatSetType(C,((PetscObject)A)->type_name));
1809566063dSJacob Faibussowitsch       PetscCall(MatSetUp(C));
1819566063dSJacob Faibussowitsch       PetscCall(MatSetOption(C,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_FALSE));
1829566063dSJacob Faibussowitsch       PetscCall(MatGetOwnershipRange(B,&Istart,&Iend));
18309baa881SHong Zhang 
18409baa881SHong Zhang       for (row = Istart; row < Iend; row++) {
1859566063dSJacob Faibussowitsch         PetscCall(MatGetRow(B,row,&bncols,&bcols,&bvals));
1869566063dSJacob Faibussowitsch         PetscCall(PetscMalloc2(bncols,&ccols,bncols,&cvals));
18709baa881SHong Zhang         for (j = 0, cncols = 0; j < bncols; j++) {
18809baa881SHong Zhang           if (PetscAbsScalar(bvals[j]) > threshold) {
18909baa881SHong Zhang             ccols[cncols] = bcols[j];
19009baa881SHong Zhang             cvals[cncols] = bvals[j];
19109baa881SHong Zhang             cncols += 1;
19209baa881SHong Zhang           }
19309baa881SHong Zhang         }
19409baa881SHong Zhang         if (cncols) {
1959566063dSJacob Faibussowitsch           PetscCall(MatSetValues(C,1,&row,cncols,ccols,cvals,INSERT_VALUES));
19609baa881SHong Zhang         }
1979566063dSJacob Faibussowitsch         PetscCall(MatRestoreRow(B,row,&bncols,&bcols,&bvals));
1989566063dSJacob Faibussowitsch         PetscCall(PetscFree2(ccols,cvals));
19909baa881SHong Zhang       }
2009566063dSJacob Faibussowitsch       PetscCall(MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY));
2019566063dSJacob Faibussowitsch       PetscCall(MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY));
2029566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer,"  Finite-difference minus hand-coded Hessian with tolerance %g ----------\n",(double)threshold));
2039566063dSJacob Faibussowitsch       PetscCall(MatView(C,mviewer));
2049566063dSJacob Faibussowitsch       PetscCall(MatDestroy(&C));
20509baa881SHong Zhang     }
2069566063dSJacob Faibussowitsch     PetscCall(MatDestroy(&A));
2079566063dSJacob Faibussowitsch     PetscCall(MatDestroy(&B));
20809baa881SHong Zhang 
20909baa881SHong Zhang     if (hessian != tao->hessian_pre) {
21009baa881SHong Zhang       hessian = tao->hessian_pre;
2119566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer,"  ---------- Testing Hessian for preconditioner -------------\n"));
21209baa881SHong Zhang     } else hessian = NULL;
21309baa881SHong Zhang   }
214f49d1c87SHong Zhang   if (complete_print) {
2159566063dSJacob Faibussowitsch     PetscCall(PetscViewerPopFormat(mviewer));
2169566063dSJacob Faibussowitsch     PetscCall(PetscViewerDestroy(&mviewer));
217f49d1c87SHong Zhang   }
2189566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIISetTab(viewer,tabs));
21909baa881SHong Zhang   PetscFunctionReturn(0);
22009baa881SHong Zhang }
22109baa881SHong Zhang 
222a7e14dcfSSatish Balay /*@C
223a7e14dcfSSatish Balay    TaoComputeHessian - Computes the Hessian matrix that has been
224*65ba42b6SBarry Smith    set with `TaoSetHessian()`.
225a7e14dcfSSatish Balay 
226*65ba42b6SBarry Smith    Collective on tao
227a7e14dcfSSatish Balay 
228a7e14dcfSSatish Balay    Input Parameters:
229f4c1ad5cSStefano Zampini +  tao - the Tao solver context
230f4c1ad5cSStefano Zampini -  X   - input vector
231a7e14dcfSSatish Balay 
232a7e14dcfSSatish Balay    Output Parameters:
233a7e14dcfSSatish Balay +  H    - Hessian matrix
234aa6c7ce3SBarry Smith -  Hpre - Preconditioning matrix
235a7e14dcfSSatish Balay 
23609baa881SHong Zhang    Options Database Keys:
23709baa881SHong Zhang +     -tao_test_hessian - compare the user provided Hessian with one compute via finite differences to check for errors
23809baa881SHong 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
239dfe02fe6SHong 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
24009baa881SHong Zhang 
241a7e14dcfSSatish Balay    Notes:
242a7e14dcfSSatish Balay    Most users should not need to explicitly call this routine, as it
243a7e14dcfSSatish Balay    is used internally within the minimization solvers.
244a7e14dcfSSatish Balay 
245*65ba42b6SBarry Smith    `TaoComputeHessian()` is typically used within optimization algorithms,
246*65ba42b6SBarry Smith    so most users would not generally call this routine
247a7e14dcfSSatish Balay    themselves.
248a7e14dcfSSatish Balay 
249*65ba42b6SBarry Smith    Developer Note:
250*65ba42b6SBarry Smith    The Hessian test mechanism follows `SNESTestJacobian()`.
25109baa881SHong Zhang 
252a7e14dcfSSatish Balay    Level: developer
253a7e14dcfSSatish Balay 
254*65ba42b6SBarry Smith .seealso: `Tao`, `TaoComputeObjective()`, `TaoComputeObjectiveAndGradient()`, `TaoSetHessian()`
255a7e14dcfSSatish Balay @*/
256ffad9901SBarry Smith PetscErrorCode TaoComputeHessian(Tao tao, Vec X, Mat H, Mat Hpre)
257a7e14dcfSSatish Balay {
258a7e14dcfSSatish Balay   PetscFunctionBegin;
259441846f8SBarry Smith   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
260a7e14dcfSSatish Balay   PetscValidHeaderSpecific(X, VEC_CLASSID,2);
261a7e14dcfSSatish Balay   PetscCheckSameComm(tao,1,X,2);
2623c859ba3SBarry Smith   PetscCheck(tao->ops->computehessian,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Must call TaoSetHessian() first");
263a7e14dcfSSatish Balay   ++tao->nhess;
2649566063dSJacob Faibussowitsch   PetscCall(VecLockReadPush(X));
2659566063dSJacob Faibussowitsch   PetscCall(PetscLogEventBegin(TAO_HessianEval,tao,X,H,Hpre));
266441846f8SBarry Smith   PetscStackPush("Tao user Hessian function");
2679566063dSJacob Faibussowitsch   PetscCall((*tao->ops->computehessian)(tao,X,H,Hpre,tao->user_hessP));
268a7e14dcfSSatish Balay   PetscStackPop;
2699566063dSJacob Faibussowitsch   PetscCall(PetscLogEventEnd(TAO_HessianEval,tao,X,H,Hpre));
2709566063dSJacob Faibussowitsch   PetscCall(VecLockReadPop(X));
27109baa881SHong Zhang 
2729566063dSJacob Faibussowitsch   PetscCall(TaoTestHessian(tao));
273a7e14dcfSSatish Balay   PetscFunctionReturn(0);
274a7e14dcfSSatish Balay }
275a7e14dcfSSatish Balay 
276a7e14dcfSSatish Balay /*@C
277a7e14dcfSSatish Balay    TaoComputeJacobian - Computes the Jacobian matrix that has been
278a7e14dcfSSatish Balay    set with TaoSetJacobianRoutine().
279a7e14dcfSSatish Balay 
280*65ba42b6SBarry Smith    Collective on tao
281a7e14dcfSSatish Balay 
282a7e14dcfSSatish Balay    Input Parameters:
283f4c1ad5cSStefano Zampini +  tao - the Tao solver context
284f4c1ad5cSStefano Zampini -  X   - input vector
285a7e14dcfSSatish Balay 
286a7e14dcfSSatish Balay    Output Parameters:
287f4c1ad5cSStefano Zampini +  J    - Jacobian matrix
288f4c1ad5cSStefano Zampini -  Jpre - Preconditioning matrix
289a7e14dcfSSatish Balay 
290a7e14dcfSSatish Balay    Notes:
291a7e14dcfSSatish Balay    Most users should not need to explicitly call this routine, as it
292a7e14dcfSSatish Balay    is used internally within the minimization solvers.
293a7e14dcfSSatish Balay 
294*65ba42b6SBarry Smith    `TaoComputeJacobian()` is typically used within minimization
295a7e14dcfSSatish Balay    implementations, so most users would not generally call this routine
296a7e14dcfSSatish Balay    themselves.
297a7e14dcfSSatish Balay 
298a7e14dcfSSatish Balay    Level: developer
299a7e14dcfSSatish Balay 
300db781477SPatrick Sanan .seealso: `TaoComputeObjective()`, `TaoComputeObjectiveAndGradient()`, `TaoSetJacobianRoutine()`
301a7e14dcfSSatish Balay @*/
302ffad9901SBarry Smith PetscErrorCode TaoComputeJacobian(Tao tao, Vec X, Mat J, Mat Jpre)
303a7e14dcfSSatish Balay {
304a7e14dcfSSatish Balay   PetscFunctionBegin;
305441846f8SBarry Smith   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
306a7e14dcfSSatish Balay   PetscValidHeaderSpecific(X, VEC_CLASSID,2);
307a7e14dcfSSatish Balay   PetscCheckSameComm(tao,1,X,2);
3083c859ba3SBarry Smith   PetscCheck(tao->ops->computejacobian,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Must call TaoSetJacobian() first");
309a7e14dcfSSatish Balay   ++tao->njac;
3109566063dSJacob Faibussowitsch   PetscCall(VecLockReadPush(X));
3119566063dSJacob Faibussowitsch   PetscCall(PetscLogEventBegin(TAO_JacobianEval,tao,X,J,Jpre));
312441846f8SBarry Smith   PetscStackPush("Tao user Jacobian function");
3139566063dSJacob Faibussowitsch   PetscCall((*tao->ops->computejacobian)(tao,X,J,Jpre,tao->user_jacP));
314a7e14dcfSSatish Balay   PetscStackPop;
3159566063dSJacob Faibussowitsch   PetscCall(PetscLogEventEnd(TAO_JacobianEval,tao,X,J,Jpre));
3169566063dSJacob Faibussowitsch   PetscCall(VecLockReadPop(X));
317a7e14dcfSSatish Balay   PetscFunctionReturn(0);
318a7e14dcfSSatish Balay }
319a7e14dcfSSatish Balay 
320a7e14dcfSSatish Balay /*@C
3214a48860cSAlp Dener    TaoComputeResidualJacobian - Computes the least-squares residual Jacobian matrix that has been
322*65ba42b6SBarry Smith    set with `TaoSetJacobianResidual()`.
3234a48860cSAlp Dener 
324*65ba42b6SBarry Smith    Collective on tao
3254a48860cSAlp Dener 
3264a48860cSAlp Dener    Input Parameters:
3274a48860cSAlp Dener +  tao - the Tao solver context
3284a48860cSAlp Dener -  X   - input vector
3294a48860cSAlp Dener 
3304a48860cSAlp Dener    Output Parameters:
3314a48860cSAlp Dener +  J    - Jacobian matrix
3324a48860cSAlp Dener -  Jpre - Preconditioning matrix
3334a48860cSAlp Dener 
3344a48860cSAlp Dener    Notes:
3354a48860cSAlp Dener    Most users should not need to explicitly call this routine, as it
3364a48860cSAlp Dener    is used internally within the minimization solvers.
3374a48860cSAlp Dener 
338*65ba42b6SBarry Smith    `TaoComputeResidualJacobian()` is typically used within least-squares
3394a48860cSAlp Dener    implementations, so most users would not generally call this routine
3404a48860cSAlp Dener    themselves.
3414a48860cSAlp Dener 
3424a48860cSAlp Dener    Level: developer
3434a48860cSAlp Dener 
344*65ba42b6SBarry Smith .seealso: `Tao`, `TaoComputeResidual()`, `TaoSetJacobianResidual()`
3454a48860cSAlp Dener @*/
3464a48860cSAlp Dener PetscErrorCode TaoComputeResidualJacobian(Tao tao, Vec X, Mat J, Mat Jpre)
3474a48860cSAlp Dener {
3484a48860cSAlp Dener   PetscFunctionBegin;
3494a48860cSAlp Dener   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
3504a48860cSAlp Dener   PetscValidHeaderSpecific(X, VEC_CLASSID,2);
3514a48860cSAlp Dener   PetscCheckSameComm(tao,1,X,2);
3523c859ba3SBarry Smith   PetscCheck(tao->ops->computeresidualjacobian,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Must call TaoSetResidualJacobian() first");
3534a48860cSAlp Dener   ++tao->njac;
3549566063dSJacob Faibussowitsch   PetscCall(VecLockReadPush(X));
3559566063dSJacob Faibussowitsch   PetscCall(PetscLogEventBegin(TAO_JacobianEval,tao,X,J,Jpre));
3564a48860cSAlp Dener   PetscStackPush("Tao user least-squares residual Jacobian function");
3579566063dSJacob Faibussowitsch   PetscCall((*tao->ops->computeresidualjacobian)(tao,X,J,Jpre,tao->user_lsjacP));
3584a48860cSAlp Dener   PetscStackPop;
3599566063dSJacob Faibussowitsch   PetscCall(PetscLogEventEnd(TAO_JacobianEval,tao,X,J,Jpre));
3609566063dSJacob Faibussowitsch   PetscCall(VecLockReadPop(X));
3614a48860cSAlp Dener   PetscFunctionReturn(0);
3624a48860cSAlp Dener }
3634a48860cSAlp Dener 
3644a48860cSAlp Dener /*@C
365a7e14dcfSSatish Balay    TaoComputeJacobianState - Computes the Jacobian matrix that has been
366*65ba42b6SBarry Smith    set with `TaoSetJacobianStateRoutine()`.
367a7e14dcfSSatish Balay 
368*65ba42b6SBarry Smith    Collective on tao
369a7e14dcfSSatish Balay 
370a7e14dcfSSatish Balay    Input Parameters:
371f4c1ad5cSStefano Zampini +  tao - the Tao solver context
372f4c1ad5cSStefano Zampini -  X   - input vector
373a7e14dcfSSatish Balay 
374a7e14dcfSSatish Balay    Output Parameters:
3756b867d5aSJose E. Roman +  J    - Jacobian matrix
3766b867d5aSJose E. Roman .  Jpre - Preconditioning matrix
377*65ba42b6SBarry Smith -  Jinv - unknown
378a7e14dcfSSatish Balay 
379a7e14dcfSSatish Balay    Notes:
380a7e14dcfSSatish Balay    Most users should not need to explicitly call this routine, as it
381*65ba42b6SBarry Smith    is used internally within the optimization algorithms.
382a7e14dcfSSatish Balay 
383a7e14dcfSSatish Balay    Level: developer
384a7e14dcfSSatish Balay 
385*65ba42b6SBarry Smith .seealso: `Tao`, `TaoComputeObjective()`, `TaoComputeObjectiveAndGradient()`, `TaoSetJacobianStateRoutine()`, `TaoComputeJacobianDesign()`, `TaoSetStateDesignIS()`
386a7e14dcfSSatish Balay @*/
387ffad9901SBarry Smith PetscErrorCode TaoComputeJacobianState(Tao tao, Vec X, Mat J, Mat Jpre, Mat Jinv)
388a7e14dcfSSatish Balay {
389a7e14dcfSSatish Balay   PetscFunctionBegin;
390441846f8SBarry Smith   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
391a7e14dcfSSatish Balay   PetscValidHeaderSpecific(X, VEC_CLASSID,2);
392a7e14dcfSSatish Balay   PetscCheckSameComm(tao,1,X,2);
3933c859ba3SBarry Smith   PetscCheck(tao->ops->computejacobianstate,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Must call TaoSetJacobianState() first");
394a7e14dcfSSatish Balay   ++tao->njac_state;
3959566063dSJacob Faibussowitsch   PetscCall(VecLockReadPush(X));
3969566063dSJacob Faibussowitsch   PetscCall(PetscLogEventBegin(TAO_JacobianEval,tao,X,J,Jpre));
397441846f8SBarry Smith   PetscStackPush("Tao user Jacobian(state) function");
3989566063dSJacob Faibussowitsch   PetscCall((*tao->ops->computejacobianstate)(tao,X,J,Jpre,Jinv,tao->user_jac_stateP));
399a7e14dcfSSatish Balay   PetscStackPop;
4009566063dSJacob Faibussowitsch   PetscCall(PetscLogEventEnd(TAO_JacobianEval,tao,X,J,Jpre));
4019566063dSJacob Faibussowitsch   PetscCall(VecLockReadPop(X));
402a7e14dcfSSatish Balay   PetscFunctionReturn(0);
403a7e14dcfSSatish Balay }
404a7e14dcfSSatish Balay 
405a7e14dcfSSatish Balay /*@C
406a7e14dcfSSatish Balay    TaoComputeJacobianDesign - Computes the Jacobian matrix that has been
407*65ba42b6SBarry Smith    set with `TaoSetJacobianDesignRoutine()`.
408a7e14dcfSSatish Balay 
409*65ba42b6SBarry Smith    Collective on tao
410a7e14dcfSSatish Balay 
411a7e14dcfSSatish Balay    Input Parameters:
412f4c1ad5cSStefano Zampini +  tao - the Tao solver context
413f4c1ad5cSStefano Zampini -  X   - input vector
414a7e14dcfSSatish Balay 
415a7e14dcfSSatish Balay    Output Parameters:
416f4c1ad5cSStefano Zampini .  J - Jacobian matrix
417a7e14dcfSSatish Balay 
418a7e14dcfSSatish Balay    Notes:
419a7e14dcfSSatish Balay    Most users should not need to explicitly call this routine, as it
420*65ba42b6SBarry Smith    is used internally within the optimization algorithms.
421a7e14dcfSSatish Balay 
422a7e14dcfSSatish Balay    Level: developer
423a7e14dcfSSatish Balay 
424*65ba42b6SBarry Smith .seealso: `Tao`, `TaoComputeObjective()`, `TaoComputeObjectiveAndGradient()`, `TaoSetJacobianDesignRoutine()`, `TaoComputeJacobianDesign()`, `TaoSetStateDesignIS()`
425a7e14dcfSSatish Balay @*/
42694ab13aaSBarry Smith PetscErrorCode TaoComputeJacobianDesign(Tao tao, Vec X, Mat J)
427a7e14dcfSSatish Balay {
428a7e14dcfSSatish Balay   PetscFunctionBegin;
429441846f8SBarry Smith   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
430a7e14dcfSSatish Balay   PetscValidHeaderSpecific(X, VEC_CLASSID,2);
431a7e14dcfSSatish Balay   PetscCheckSameComm(tao,1,X,2);
4323c859ba3SBarry Smith   PetscCheck(tao->ops->computejacobiandesign,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Must call TaoSetJacobianDesign() first");
433a7e14dcfSSatish Balay   ++tao->njac_design;
4349566063dSJacob Faibussowitsch   PetscCall(VecLockReadPush(X));
4359566063dSJacob Faibussowitsch   PetscCall(PetscLogEventBegin(TAO_JacobianEval,tao,X,J,NULL));
436441846f8SBarry Smith   PetscStackPush("Tao user Jacobian(design) function");
4379566063dSJacob Faibussowitsch   PetscCall((*tao->ops->computejacobiandesign)(tao,X,J,tao->user_jac_designP));
438a7e14dcfSSatish Balay   PetscStackPop;
4399566063dSJacob Faibussowitsch   PetscCall(PetscLogEventEnd(TAO_JacobianEval,tao,X,J,NULL));
4409566063dSJacob Faibussowitsch   PetscCall(VecLockReadPop(X));
441a7e14dcfSSatish Balay   PetscFunctionReturn(0);
442a7e14dcfSSatish Balay }
443a7e14dcfSSatish Balay 
444a7e14dcfSSatish Balay /*@C
445a7e14dcfSSatish Balay    TaoSetJacobianRoutine - Sets the function to compute the Jacobian as well as the location to store the matrix.
446a7e14dcfSSatish Balay 
447*65ba42b6SBarry Smith    Logically collective on tao
448a7e14dcfSSatish Balay 
449a7e14dcfSSatish Balay    Input Parameters:
450441846f8SBarry Smith +  tao  - the Tao context
451a7e14dcfSSatish Balay .  J    - Matrix used for the jacobian
452a7e14dcfSSatish Balay .  Jpre - Matrix that will be used operated on by preconditioner, can be same as J
453f4c1ad5cSStefano Zampini .  func - Jacobian evaluation routine
454a7e14dcfSSatish Balay -  ctx  - [optional] user-defined context for private data for the
4556c23d075SBarry Smith           Jacobian evaluation routine (may be NULL)
456a7e14dcfSSatish Balay 
457f4c1ad5cSStefano Zampini    Calling sequence of func:
458f4c1ad5cSStefano Zampini $    func(Tao tao,Vec x,Mat J,Mat Jpre,void *ctx);
459a7e14dcfSSatish Balay 
460441846f8SBarry Smith +  tao  - the Tao  context
461a7e14dcfSSatish Balay .  x    - input vector
462a7e14dcfSSatish Balay .  J    - Jacobian matrix
463f4c1ad5cSStefano Zampini .  Jpre - preconditioning matrix, usually the same as J
464a7e14dcfSSatish Balay -  ctx  - [optional] user-defined Jacobian context
465a7e14dcfSSatish Balay 
466a7e14dcfSSatish Balay    Level: intermediate
467*65ba42b6SBarry Smith 
468*65ba42b6SBarry Smith .seealso: `Tao`, `TaoSetGradient()`, `TaoSetObjective()`
469a7e14dcfSSatish Balay @*/
470ffad9901SBarry Smith PetscErrorCode TaoSetJacobianRoutine(Tao tao, Mat J, Mat Jpre, PetscErrorCode (*func)(Tao, Vec, Mat, Mat, void*), void *ctx)
471a7e14dcfSSatish Balay {
472a7e14dcfSSatish Balay   PetscFunctionBegin;
473441846f8SBarry Smith   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
474a7e14dcfSSatish Balay   if (J) {
475a7e14dcfSSatish Balay     PetscValidHeaderSpecific(J,MAT_CLASSID,2);
476a7e14dcfSSatish Balay     PetscCheckSameComm(tao,1,J,2);
477a7e14dcfSSatish Balay   }
478a7e14dcfSSatish Balay   if (Jpre) {
479a7e14dcfSSatish Balay     PetscValidHeaderSpecific(Jpre,MAT_CLASSID,3);
480a7e14dcfSSatish Balay     PetscCheckSameComm(tao,1,Jpre,3);
481a7e14dcfSSatish Balay   }
482a7e14dcfSSatish Balay   if (ctx) {
483a7e14dcfSSatish Balay     tao->user_jacP = ctx;
484a7e14dcfSSatish Balay   }
485a7e14dcfSSatish Balay   if (func) {
486a7e14dcfSSatish Balay     tao->ops->computejacobian = func;
487a7e14dcfSSatish Balay   }
488a7e14dcfSSatish Balay   if (J) {
4899566063dSJacob Faibussowitsch     PetscCall(PetscObjectReference((PetscObject)J));
4909566063dSJacob Faibussowitsch     PetscCall(MatDestroy(&tao->jacobian));
491a7e14dcfSSatish Balay     tao->jacobian = J;
492a7e14dcfSSatish Balay   }
493a7e14dcfSSatish Balay   if (Jpre) {
4949566063dSJacob Faibussowitsch     PetscCall(PetscObjectReference((PetscObject)Jpre));
4959566063dSJacob Faibussowitsch     PetscCall(MatDestroy(&tao->jacobian_pre));
496a7e14dcfSSatish Balay     tao->jacobian_pre=Jpre;
497a7e14dcfSSatish Balay   }
498a7e14dcfSSatish Balay   PetscFunctionReturn(0);
499a7e14dcfSSatish Balay }
500a7e14dcfSSatish Balay 
501a7e14dcfSSatish Balay /*@C
5024ffbe8acSAlp Dener    TaoSetJacobianResidualRoutine - Sets the function to compute the least-squares residual Jacobian as well as the
5034a48860cSAlp Dener    location to store the matrix.
5044a48860cSAlp Dener 
505*65ba42b6SBarry Smith    Logically collective on tao
5064a48860cSAlp Dener 
5074a48860cSAlp Dener    Input Parameters:
5084a48860cSAlp Dener +  tao  - the Tao context
5094a48860cSAlp Dener .  J    - Matrix used for the jacobian
5104a48860cSAlp Dener .  Jpre - Matrix that will be used operated on by preconditioner, can be same as J
5114a48860cSAlp Dener .  func - Jacobian evaluation routine
5124a48860cSAlp Dener -  ctx  - [optional] user-defined context for private data for the
5134a48860cSAlp Dener           Jacobian evaluation routine (may be NULL)
5144a48860cSAlp Dener 
5154a48860cSAlp Dener    Calling sequence of func:
5164a48860cSAlp Dener $    func(Tao tao,Vec x,Mat J,Mat Jpre,void *ctx);
5174a48860cSAlp Dener 
5184a48860cSAlp Dener +  tao  - the Tao  context
5194a48860cSAlp Dener .  x    - input vector
5204a48860cSAlp Dener .  J    - Jacobian matrix
5214a48860cSAlp Dener .  Jpre - preconditioning matrix, usually the same as J
5224a48860cSAlp Dener -  ctx  - [optional] user-defined Jacobian context
5234a48860cSAlp Dener 
5244a48860cSAlp Dener    Level: intermediate
525*65ba42b6SBarry Smith 
526*65ba42b6SBarry Smith .seealso: `Tao`, `TaoSetGradient()`, `TaoSetObjective()`
5274a48860cSAlp Dener @*/
5284ffbe8acSAlp Dener PetscErrorCode TaoSetJacobianResidualRoutine(Tao tao, Mat J, Mat Jpre, PetscErrorCode (*func)(Tao, Vec, Mat, Mat, void*), void *ctx)
5294a48860cSAlp Dener {
5304a48860cSAlp Dener   PetscFunctionBegin;
5314a48860cSAlp Dener   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
5324a48860cSAlp Dener   if (J) {
5334a48860cSAlp Dener     PetscValidHeaderSpecific(J,MAT_CLASSID,2);
5344a48860cSAlp Dener     PetscCheckSameComm(tao,1,J,2);
5354a48860cSAlp Dener   }
5364a48860cSAlp Dener   if (Jpre) {
5374a48860cSAlp Dener     PetscValidHeaderSpecific(Jpre,MAT_CLASSID,3);
5384a48860cSAlp Dener     PetscCheckSameComm(tao,1,Jpre,3);
5394a48860cSAlp Dener   }
5404a48860cSAlp Dener   if (ctx) {
5414a48860cSAlp Dener     tao->user_lsjacP = ctx;
5424a48860cSAlp Dener   }
5434a48860cSAlp Dener   if (func) {
5444a48860cSAlp Dener     tao->ops->computeresidualjacobian = func;
5454a48860cSAlp Dener   }
5464a48860cSAlp Dener   if (J) {
5479566063dSJacob Faibussowitsch     PetscCall(PetscObjectReference((PetscObject)J));
5489566063dSJacob Faibussowitsch     PetscCall(MatDestroy(&tao->ls_jac));
5494a48860cSAlp Dener     tao->ls_jac = J;
5504a48860cSAlp Dener   }
5514a48860cSAlp Dener   if (Jpre) {
5529566063dSJacob Faibussowitsch     PetscCall(PetscObjectReference((PetscObject)Jpre));
5539566063dSJacob Faibussowitsch     PetscCall(MatDestroy(&tao->ls_jac_pre));
5544a48860cSAlp Dener     tao->ls_jac_pre=Jpre;
5554a48860cSAlp Dener   }
5564a48860cSAlp Dener   PetscFunctionReturn(0);
5574a48860cSAlp Dener }
5584a48860cSAlp Dener 
5594a48860cSAlp Dener /*@C
560a7e14dcfSSatish Balay    TaoSetJacobianStateRoutine - Sets the function to compute the Jacobian
561a7e14dcfSSatish Balay    (and its inverse) of the constraint function with respect to the state variables.
562*65ba42b6SBarry Smith    Used only for PDE-constrained optimization.
563a7e14dcfSSatish Balay 
564*65ba42b6SBarry Smith    Logically collective on tao
565a7e14dcfSSatish Balay 
566a7e14dcfSSatish Balay    Input Parameters:
567441846f8SBarry Smith +  tao  - the Tao context
568a7e14dcfSSatish Balay .  J    - Matrix used for the jacobian
5696c23d075SBarry Smith .  Jpre - Matrix that will be used operated on by PETSc preconditioner, can be same as J.  Only used if Jinv is NULL
5706c23d075SBarry 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.
571f4c1ad5cSStefano Zampini .  func - Jacobian evaluation routine
572a7e14dcfSSatish Balay -  ctx  - [optional] user-defined context for private data for the
5736c23d075SBarry Smith           Jacobian evaluation routine (may be NULL)
574a7e14dcfSSatish Balay 
575f4c1ad5cSStefano Zampini    Calling sequence of func:
576f4c1ad5cSStefano Zampini $    func(Tao tao,Vec x,Mat J,Mat Jpre,Mat Jinv,void *ctx);
577a7e14dcfSSatish Balay 
578441846f8SBarry Smith +  tao  - the Tao  context
579a7e14dcfSSatish Balay .  x    - input vector
580a7e14dcfSSatish Balay .  J    - Jacobian matrix
581a7e14dcfSSatish Balay .  Jpre - preconditioner matrix, usually the same as J
582a7e14dcfSSatish Balay .  Jinv - inverse of J
583a7e14dcfSSatish Balay -  ctx  - [optional] user-defined Jacobian context
584a7e14dcfSSatish Balay 
585a7e14dcfSSatish Balay    Level: intermediate
586*65ba42b6SBarry Smith 
587*65ba42b6SBarry Smith .seealso: `Tao`, `TaoComputeJacobianState()`, `TaoSetJacobianDesignRoutine()`, `TaoSetStateDesignIS()`
588a7e14dcfSSatish Balay @*/
589ffad9901SBarry Smith PetscErrorCode TaoSetJacobianStateRoutine(Tao tao, Mat J, Mat Jpre, Mat Jinv, PetscErrorCode (*func)(Tao, Vec, Mat, Mat, Mat, void*), void *ctx)
590a7e14dcfSSatish Balay {
591a7e14dcfSSatish Balay   PetscFunctionBegin;
592441846f8SBarry Smith   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
593a7e14dcfSSatish Balay   if (J) {
594a7e14dcfSSatish Balay     PetscValidHeaderSpecific(J,MAT_CLASSID,2);
595a7e14dcfSSatish Balay     PetscCheckSameComm(tao,1,J,2);
596a7e14dcfSSatish Balay   }
597a7e14dcfSSatish Balay   if (Jpre) {
598a7e14dcfSSatish Balay     PetscValidHeaderSpecific(Jpre,MAT_CLASSID,3);
599a7e14dcfSSatish Balay     PetscCheckSameComm(tao,1,Jpre,3);
600a7e14dcfSSatish Balay   }
601a7e14dcfSSatish Balay   if (Jinv) {
602a7e14dcfSSatish Balay     PetscValidHeaderSpecific(Jinv,MAT_CLASSID,4);
603a7e14dcfSSatish Balay     PetscCheckSameComm(tao,1,Jinv,4);
604a7e14dcfSSatish Balay   }
605a7e14dcfSSatish Balay   if (ctx) {
606a7e14dcfSSatish Balay     tao->user_jac_stateP = ctx;
607a7e14dcfSSatish Balay   }
608a7e14dcfSSatish Balay   if (func) {
609a7e14dcfSSatish Balay     tao->ops->computejacobianstate = func;
610a7e14dcfSSatish Balay   }
611a7e14dcfSSatish Balay   if (J) {
6129566063dSJacob Faibussowitsch     PetscCall(PetscObjectReference((PetscObject)J));
6139566063dSJacob Faibussowitsch     PetscCall(MatDestroy(&tao->jacobian_state));
614a7e14dcfSSatish Balay     tao->jacobian_state = J;
615a7e14dcfSSatish Balay   }
616a7e14dcfSSatish Balay   if (Jpre) {
6179566063dSJacob Faibussowitsch     PetscCall(PetscObjectReference((PetscObject)Jpre));
6189566063dSJacob Faibussowitsch     PetscCall(MatDestroy(&tao->jacobian_state_pre));
619a7e14dcfSSatish Balay     tao->jacobian_state_pre=Jpre;
620a7e14dcfSSatish Balay   }
621a7e14dcfSSatish Balay   if (Jinv) {
6229566063dSJacob Faibussowitsch     PetscCall(PetscObjectReference((PetscObject)Jinv));
6239566063dSJacob Faibussowitsch     PetscCall(MatDestroy(&tao->jacobian_state_inv));
624a7e14dcfSSatish Balay     tao->jacobian_state_inv=Jinv;
625a7e14dcfSSatish Balay   }
626a7e14dcfSSatish Balay   PetscFunctionReturn(0);
627a7e14dcfSSatish Balay }
628a7e14dcfSSatish Balay 
629a7e14dcfSSatish Balay /*@C
630a7e14dcfSSatish Balay    TaoSetJacobianDesignRoutine - Sets the function to compute the Jacobian of
631a7e14dcfSSatish Balay    the constraint function with respect to the design variables.  Used only for
632*65ba42b6SBarry Smith    PDE-constrained optimization.
633a7e14dcfSSatish Balay 
634*65ba42b6SBarry Smith    Logically collective on tao
635a7e14dcfSSatish Balay 
636a7e14dcfSSatish Balay    Input Parameters:
637441846f8SBarry Smith +  tao  - the Tao context
638a7e14dcfSSatish Balay .  J    - Matrix used for the jacobian
639f4c1ad5cSStefano Zampini .  func - Jacobian evaluation routine
640a7e14dcfSSatish Balay -  ctx  - [optional] user-defined context for private data for the
6416c23d075SBarry Smith           Jacobian evaluation routine (may be NULL)
642a7e14dcfSSatish Balay 
643f4c1ad5cSStefano Zampini    Calling sequence of func:
644f4c1ad5cSStefano Zampini $    func(Tao tao,Vec x,Mat J,void *ctx);
645a7e14dcfSSatish Balay 
646441846f8SBarry Smith +  tao - the Tao  context
647a7e14dcfSSatish Balay .  x   - input vector
648a7e14dcfSSatish Balay .  J   - Jacobian matrix
649a7e14dcfSSatish Balay -  ctx - [optional] user-defined Jacobian context
650a7e14dcfSSatish Balay 
651a7e14dcfSSatish Balay    Level: intermediate
652f4c1ad5cSStefano Zampini 
653*65ba42b6SBarry Smith .seealso: `Tao`, `TaoComputeJacobianDesign()`, `TaoSetJacobianStateRoutine()`, `TaoSetStateDesignIS()`
654a7e14dcfSSatish Balay @*/
65594ab13aaSBarry Smith PetscErrorCode TaoSetJacobianDesignRoutine(Tao tao, Mat J, PetscErrorCode (*func)(Tao, Vec, Mat, void*), void *ctx)
656a7e14dcfSSatish Balay {
657a7e14dcfSSatish Balay   PetscFunctionBegin;
658441846f8SBarry Smith   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
659a7e14dcfSSatish Balay   if (J) {
660a7e14dcfSSatish Balay     PetscValidHeaderSpecific(J,MAT_CLASSID,2);
661a7e14dcfSSatish Balay     PetscCheckSameComm(tao,1,J,2);
662a7e14dcfSSatish Balay   }
663a7e14dcfSSatish Balay   if (ctx) {
664a7e14dcfSSatish Balay     tao->user_jac_designP = ctx;
665a7e14dcfSSatish Balay   }
666a7e14dcfSSatish Balay   if (func) {
667a7e14dcfSSatish Balay     tao->ops->computejacobiandesign = func;
668a7e14dcfSSatish Balay   }
669a7e14dcfSSatish Balay   if (J) {
6709566063dSJacob Faibussowitsch     PetscCall(PetscObjectReference((PetscObject)J));
6719566063dSJacob Faibussowitsch     PetscCall(MatDestroy(&tao->jacobian_design));
672a7e14dcfSSatish Balay     tao->jacobian_design = J;
673a7e14dcfSSatish Balay   }
674a7e14dcfSSatish Balay   PetscFunctionReturn(0);
675a7e14dcfSSatish Balay }
676a7e14dcfSSatish Balay 
677a7e14dcfSSatish Balay /*@
678441846f8SBarry Smith    TaoSetStateDesignIS - Indicate to the Tao which variables in the
679a7e14dcfSSatish Balay    solution vector are state variables and which are design.  Only applies to
680*65ba42b6SBarry Smith    PDE-constrained optimization.
681a7e14dcfSSatish Balay 
682441846f8SBarry Smith    Logically Collective on Tao
683a7e14dcfSSatish Balay 
684a7e14dcfSSatish Balay    Input Parameters:
685441846f8SBarry Smith +  tao  - The Tao context
686a7e14dcfSSatish Balay .  s_is - the index set corresponding to the state variables
687a7e14dcfSSatish Balay -  d_is - the index set corresponding to the design variables
688a7e14dcfSSatish Balay 
689a7e14dcfSSatish Balay    Level: intermediate
690a7e14dcfSSatish Balay 
691*65ba42b6SBarry Smith .seealso: `Tao`, `TaoSetJacobianStateRoutine()`, `TaoSetJacobianDesignRoutine()`
692a7e14dcfSSatish Balay @*/
693441846f8SBarry Smith PetscErrorCode TaoSetStateDesignIS(Tao tao, IS s_is, IS d_is)
694a7e14dcfSSatish Balay {
69545cf516eSBarry Smith   PetscFunctionBegin;
6969566063dSJacob Faibussowitsch   PetscCall(PetscObjectReference((PetscObject)s_is));
6979566063dSJacob Faibussowitsch   PetscCall(ISDestroy(&tao->state_is));
698a7e14dcfSSatish Balay   tao->state_is = s_is;
6999566063dSJacob Faibussowitsch   PetscCall(PetscObjectReference((PetscObject)(d_is)));
7009566063dSJacob Faibussowitsch   PetscCall(ISDestroy(&tao->design_is));
701a7e14dcfSSatish Balay   tao->design_is = d_is;
702a7e14dcfSSatish Balay   PetscFunctionReturn(0);
703a7e14dcfSSatish Balay }
704a7e14dcfSSatish Balay 
705a7e14dcfSSatish Balay /*@C
706a7e14dcfSSatish Balay    TaoComputeJacobianEquality - Computes the Jacobian matrix that has been
707*65ba42b6SBarry Smith    set with `TaoSetJacobianEqualityRoutine()`.
708a7e14dcfSSatish Balay 
709*65ba42b6SBarry Smith    Collective on tao
710a7e14dcfSSatish Balay 
711a7e14dcfSSatish Balay    Input Parameters:
712f4c1ad5cSStefano Zampini +  tao - the Tao solver context
713f4c1ad5cSStefano Zampini -  X   - input vector
714a7e14dcfSSatish Balay 
715a7e14dcfSSatish Balay    Output Parameters:
716f4c1ad5cSStefano Zampini +  J    - Jacobian matrix
717f4c1ad5cSStefano Zampini -  Jpre - Preconditioning matrix
718a7e14dcfSSatish Balay 
719a7e14dcfSSatish Balay    Notes:
720a7e14dcfSSatish Balay    Most users should not need to explicitly call this routine, as it
721*65ba42b6SBarry Smith    is used internally within the optimization algorithms.
722a7e14dcfSSatish Balay 
723a7e14dcfSSatish Balay    Level: developer
724a7e14dcfSSatish Balay 
725db781477SPatrick Sanan .seealso: `TaoComputeObjective()`, `TaoComputeObjectiveAndGradient()`, `TaoSetJacobianStateRoutine()`, `TaoComputeJacobianDesign()`, `TaoSetStateDesignIS()`
726a7e14dcfSSatish Balay @*/
727ffad9901SBarry Smith PetscErrorCode TaoComputeJacobianEquality(Tao tao, Vec X, Mat J, Mat Jpre)
728a7e14dcfSSatish Balay {
729a7e14dcfSSatish Balay   PetscFunctionBegin;
730441846f8SBarry Smith   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
731a7e14dcfSSatish Balay   PetscValidHeaderSpecific(X, VEC_CLASSID,2);
732a7e14dcfSSatish Balay   PetscCheckSameComm(tao,1,X,2);
7333c859ba3SBarry Smith   PetscCheck(tao->ops->computejacobianequality,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Must call TaoSetJacobianEquality() first");
734a7e14dcfSSatish Balay   ++tao->njac_equality;
7359566063dSJacob Faibussowitsch   PetscCall(VecLockReadPush(X));
7369566063dSJacob Faibussowitsch   PetscCall(PetscLogEventBegin(TAO_JacobianEval,tao,X,J,Jpre));
737441846f8SBarry Smith   PetscStackPush("Tao user Jacobian(equality) function");
7389566063dSJacob Faibussowitsch   PetscCall((*tao->ops->computejacobianequality)(tao,X,J,Jpre,tao->user_jac_equalityP));
739a7e14dcfSSatish Balay   PetscStackPop;
7409566063dSJacob Faibussowitsch   PetscCall(PetscLogEventEnd(TAO_JacobianEval,tao,X,J,Jpre));
7419566063dSJacob Faibussowitsch   PetscCall(VecLockReadPop(X));
742a7e14dcfSSatish Balay   PetscFunctionReturn(0);
743a7e14dcfSSatish Balay }
744a7e14dcfSSatish Balay 
745a7e14dcfSSatish Balay /*@C
746a7e14dcfSSatish Balay    TaoComputeJacobianInequality - Computes the Jacobian matrix that has been
747*65ba42b6SBarry Smith    set with `TaoSetJacobianInequalityRoutine()`.
748a7e14dcfSSatish Balay 
749*65ba42b6SBarry Smith    Collective on tao
750a7e14dcfSSatish Balay 
751a7e14dcfSSatish Balay    Input Parameters:
752f4c1ad5cSStefano Zampini +  tao - the Tao solver context
753f4c1ad5cSStefano Zampini -  X   - input vector
754a7e14dcfSSatish Balay 
755a7e14dcfSSatish Balay    Output Parameters:
756f4c1ad5cSStefano Zampini +  J    - Jacobian matrix
757f4c1ad5cSStefano Zampini -  Jpre - Preconditioning matrix
758a7e14dcfSSatish Balay 
759a7e14dcfSSatish Balay    Notes:
760a7e14dcfSSatish Balay    Most users should not need to explicitly call this routine, as it
761a7e14dcfSSatish Balay    is used internally within the minimization solvers.
762a7e14dcfSSatish Balay 
763a7e14dcfSSatish Balay    Level: developer
764a7e14dcfSSatish Balay 
765*65ba42b6SBarry Smith .seealso: `Tao`, `TaoComputeObjective()`, `TaoComputeObjectiveAndGradient()`, `TaoSetJacobianStateRoutine()`, `TaoComputeJacobianDesign()`, `TaoSetStateDesignIS()`
766a7e14dcfSSatish Balay @*/
767ffad9901SBarry Smith PetscErrorCode TaoComputeJacobianInequality(Tao tao, Vec X, Mat J, Mat Jpre)
768a7e14dcfSSatish Balay {
769a7e14dcfSSatish Balay   PetscFunctionBegin;
770441846f8SBarry Smith   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
771a7e14dcfSSatish Balay   PetscValidHeaderSpecific(X, VEC_CLASSID,2);
772a7e14dcfSSatish Balay   PetscCheckSameComm(tao,1,X,2);
7733c859ba3SBarry Smith   PetscCheck(tao->ops->computejacobianinequality,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Must call TaoSetJacobianInequality() first");
774a7e14dcfSSatish Balay   ++tao->njac_inequality;
7759566063dSJacob Faibussowitsch   PetscCall(VecLockReadPush(X));
7769566063dSJacob Faibussowitsch   PetscCall(PetscLogEventBegin(TAO_JacobianEval,tao,X,J,Jpre));
777441846f8SBarry Smith   PetscStackPush("Tao user Jacobian(inequality) function");
7789566063dSJacob Faibussowitsch   PetscCall((*tao->ops->computejacobianinequality)(tao,X,J,Jpre,tao->user_jac_inequalityP));
779a7e14dcfSSatish Balay   PetscStackPop;
7809566063dSJacob Faibussowitsch   PetscCall(PetscLogEventEnd(TAO_JacobianEval,tao,X,J,Jpre));
7819566063dSJacob Faibussowitsch   PetscCall(VecLockReadPop(X));
782a7e14dcfSSatish Balay   PetscFunctionReturn(0);
783a7e14dcfSSatish Balay }
784a7e14dcfSSatish Balay 
785a7e14dcfSSatish Balay /*@C
786a7e14dcfSSatish Balay    TaoSetJacobianEqualityRoutine - Sets the function to compute the Jacobian
787a7e14dcfSSatish Balay    (and its inverse) of the constraint function with respect to the equality variables.
788*65ba42b6SBarry Smith    Used only for PDE-constrained optimization.
789a7e14dcfSSatish Balay 
790*65ba42b6SBarry Smith    Logically collective on tao
791a7e14dcfSSatish Balay 
792a7e14dcfSSatish Balay    Input Parameters:
793441846f8SBarry Smith +  tao  - the Tao context
794a7e14dcfSSatish Balay .  J    - Matrix used for the jacobian
795a7e14dcfSSatish Balay .  Jpre - Matrix that will be used operated on by PETSc preconditioner, can be same as J.
796f4c1ad5cSStefano Zampini .  func - Jacobian evaluation routine
797a7e14dcfSSatish Balay -  ctx  - [optional] user-defined context for private data for the
7986c23d075SBarry Smith           Jacobian evaluation routine (may be NULL)
799a7e14dcfSSatish Balay 
800f4c1ad5cSStefano Zampini    Calling sequence of func:
801f4c1ad5cSStefano Zampini $    func(Tao tao,Vec x,Mat J,Mat Jpre,void *ctx);
802a7e14dcfSSatish Balay 
803441846f8SBarry Smith +  tao  - the Tao  context
804a7e14dcfSSatish Balay .  x    - input vector
805a7e14dcfSSatish Balay .  J    - Jacobian matrix
806a7e14dcfSSatish Balay .  Jpre - preconditioner matrix, usually the same as J
807a7e14dcfSSatish Balay -  ctx  - [optional] user-defined Jacobian context
808a7e14dcfSSatish Balay 
809a7e14dcfSSatish Balay    Level: intermediate
810f4c1ad5cSStefano Zampini 
811*65ba42b6SBarry Smith .seealso: `Tao`, `TaoComputeJacobianEquality()`, `TaoSetJacobianDesignRoutine()`, `TaoSetEqualityDesignIS()`
812a7e14dcfSSatish Balay @*/
813ffad9901SBarry Smith PetscErrorCode TaoSetJacobianEqualityRoutine(Tao tao, Mat J, Mat Jpre, PetscErrorCode (*func)(Tao, Vec, Mat, Mat, void*), void *ctx)
814a7e14dcfSSatish Balay {
815a7e14dcfSSatish Balay   PetscFunctionBegin;
816441846f8SBarry Smith   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
817a7e14dcfSSatish Balay   if (J) {
818a7e14dcfSSatish Balay     PetscValidHeaderSpecific(J,MAT_CLASSID,2);
819a7e14dcfSSatish Balay     PetscCheckSameComm(tao,1,J,2);
820a7e14dcfSSatish Balay   }
821a7e14dcfSSatish Balay   if (Jpre) {
822a7e14dcfSSatish Balay     PetscValidHeaderSpecific(Jpre,MAT_CLASSID,3);
823a7e14dcfSSatish Balay     PetscCheckSameComm(tao,1,Jpre,3);
824a7e14dcfSSatish Balay   }
825a7e14dcfSSatish Balay   if (ctx) {
826a7e14dcfSSatish Balay     tao->user_jac_equalityP = ctx;
827a7e14dcfSSatish Balay   }
828a7e14dcfSSatish Balay   if (func) {
829a7e14dcfSSatish Balay     tao->ops->computejacobianequality = func;
830a7e14dcfSSatish Balay   }
831a7e14dcfSSatish Balay   if (J) {
8329566063dSJacob Faibussowitsch     PetscCall(PetscObjectReference((PetscObject)J));
8339566063dSJacob Faibussowitsch     PetscCall(MatDestroy(&tao->jacobian_equality));
834a7e14dcfSSatish Balay     tao->jacobian_equality = J;
835a7e14dcfSSatish Balay   }
836a7e14dcfSSatish Balay   if (Jpre) {
8379566063dSJacob Faibussowitsch     PetscCall(PetscObjectReference((PetscObject)Jpre));
8389566063dSJacob Faibussowitsch     PetscCall(MatDestroy(&tao->jacobian_equality_pre));
839a7e14dcfSSatish Balay     tao->jacobian_equality_pre=Jpre;
840a7e14dcfSSatish Balay   }
841a7e14dcfSSatish Balay   PetscFunctionReturn(0);
842a7e14dcfSSatish Balay }
843a7e14dcfSSatish Balay 
844a7e14dcfSSatish Balay /*@C
845a7e14dcfSSatish Balay    TaoSetJacobianInequalityRoutine - Sets the function to compute the Jacobian
846a7e14dcfSSatish Balay    (and its inverse) of the constraint function with respect to the inequality variables.
847*65ba42b6SBarry Smith    Used only for PDE-constrained optimization.
848a7e14dcfSSatish Balay 
849*65ba42b6SBarry Smith    Logically collective on tao
850a7e14dcfSSatish Balay 
851a7e14dcfSSatish Balay    Input Parameters:
852441846f8SBarry Smith +  tao  - the Tao context
853a7e14dcfSSatish Balay .  J    - Matrix used for the jacobian
854a7e14dcfSSatish Balay .  Jpre - Matrix that will be used operated on by PETSc preconditioner, can be same as J.
855f4c1ad5cSStefano Zampini .  func - Jacobian evaluation routine
856a7e14dcfSSatish Balay -  ctx  - [optional] user-defined context for private data for the
8576c23d075SBarry Smith           Jacobian evaluation routine (may be NULL)
858a7e14dcfSSatish Balay 
859f4c1ad5cSStefano Zampini    Calling sequence of func:
860f4c1ad5cSStefano Zampini $    func(Tao tao,Vec x,Mat J,Mat Jpre,void *ctx);
861a7e14dcfSSatish Balay 
862441846f8SBarry Smith +  tao  - the Tao  context
863a7e14dcfSSatish Balay .  x    - input vector
864a7e14dcfSSatish Balay .  J    - Jacobian matrix
865a7e14dcfSSatish Balay .  Jpre - preconditioner matrix, usually the same as J
866a7e14dcfSSatish Balay -  ctx  - [optional] user-defined Jacobian context
867a7e14dcfSSatish Balay 
868a7e14dcfSSatish Balay    Level: intermediate
869f4c1ad5cSStefano Zampini 
870*65ba42b6SBarry Smith .seealso: `Tao`, `TaoComputeJacobianInequality()`, `TaoSetJacobianDesignRoutine()`, `TaoSetInequalityDesignIS()`
871a7e14dcfSSatish Balay @*/
872ffad9901SBarry Smith PetscErrorCode TaoSetJacobianInequalityRoutine(Tao tao, Mat J, Mat Jpre, PetscErrorCode (*func)(Tao, Vec, Mat, Mat,void*), void *ctx)
873a7e14dcfSSatish Balay {
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) {
8919566063dSJacob Faibussowitsch     PetscCall(PetscObjectReference((PetscObject)J));
8929566063dSJacob Faibussowitsch     PetscCall(MatDestroy(&tao->jacobian_inequality));
893a7e14dcfSSatish Balay     tao->jacobian_inequality = J;
894a7e14dcfSSatish Balay   }
895a7e14dcfSSatish Balay   if (Jpre) {
8969566063dSJacob Faibussowitsch     PetscCall(PetscObjectReference((PetscObject)Jpre));
8979566063dSJacob Faibussowitsch     PetscCall(MatDestroy(&tao->jacobian_inequality_pre));
898a7e14dcfSSatish Balay     tao->jacobian_inequality_pre=Jpre;
899a7e14dcfSSatish Balay   }
900a7e14dcfSSatish Balay   PetscFunctionReturn(0);
901a7e14dcfSSatish Balay }
902