xref: /petsc/src/tao/interface/taosolver_hj.c (revision 48a46eb9bd028bec07ec0f396b1a3abb43f14558)
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 
665ba42b6SBarry 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 
2765ba42b6SBarry Smith .seealso: `Tao`, `TaoTypes`, `TaoSetObjective()`, `TaoSetGradient()`, `TaoSetObjectiveAndGradient()`, `TaoGetHessian()`
28a7e14dcfSSatish Balay @*/
299371c9d4SSatish Balay PetscErrorCode TaoSetHessian(Tao tao, Mat H, Mat Hpre, PetscErrorCode (*func)(Tao, Vec, Mat, Mat, void *), void *ctx) {
30a7e14dcfSSatish Balay   PetscFunctionBegin;
31441846f8SBarry Smith   PetscValidHeaderSpecific(tao, TAO_CLASSID, 1);
32a7e14dcfSSatish Balay   if (H) {
33a7e14dcfSSatish Balay     PetscValidHeaderSpecific(H, MAT_CLASSID, 2);
34a7e14dcfSSatish Balay     PetscCheckSameComm(tao, 1, H, 2);
35a7e14dcfSSatish Balay   }
36a7e14dcfSSatish Balay   if (Hpre) {
37a7e14dcfSSatish Balay     PetscValidHeaderSpecific(Hpre, MAT_CLASSID, 3);
38a7e14dcfSSatish Balay     PetscCheckSameComm(tao, 1, Hpre, 3);
39a7e14dcfSSatish Balay   }
40a82e8c82SStefano Zampini   if (ctx) tao->user_hessP = ctx;
41a82e8c82SStefano Zampini   if (func) tao->ops->computehessian = func;
42a7e14dcfSSatish Balay   if (H) {
439566063dSJacob Faibussowitsch     PetscCall(PetscObjectReference((PetscObject)H));
449566063dSJacob Faibussowitsch     PetscCall(MatDestroy(&tao->hessian));
45a7e14dcfSSatish Balay     tao->hessian = H;
46a7e14dcfSSatish Balay   }
47a7e14dcfSSatish Balay   if (Hpre) {
489566063dSJacob Faibussowitsch     PetscCall(PetscObjectReference((PetscObject)Hpre));
499566063dSJacob Faibussowitsch     PetscCall(MatDestroy(&tao->hessian_pre));
50a7e14dcfSSatish Balay     tao->hessian_pre = Hpre;
51a7e14dcfSSatish Balay   }
52a7e14dcfSSatish Balay   PetscFunctionReturn(0);
53a7e14dcfSSatish Balay }
54a7e14dcfSSatish Balay 
55a82e8c82SStefano Zampini /*@C
56a82e8c82SStefano Zampini    TaoGetHessian - Gets the function to compute the Hessian as well as the location to store the matrix.
57a82e8c82SStefano Zampini 
58a82e8c82SStefano Zampini    Not collective
59a82e8c82SStefano Zampini 
60a82e8c82SStefano Zampini    Input Parameter:
61a82e8c82SStefano Zampini .  tao  - the Tao context
62a82e8c82SStefano Zampini 
63a82e8c82SStefano Zampini    OutputParameters:
64a82e8c82SStefano Zampini +  H    - Matrix used for the hessian
65a82e8c82SStefano Zampini .  Hpre - Matrix that will be used operated on by preconditioner, can be the same as H
66a82e8c82SStefano Zampini .  func - Hessian evaluation routine
67a82e8c82SStefano Zampini -  ctx  - user-defined context for private data for the Hessian evaluation routine
68a82e8c82SStefano Zampini 
69a82e8c82SStefano Zampini    Calling sequence of func:
70a82e8c82SStefano Zampini $    func(Tao tao,Vec x,Mat H,Mat Hpre,void *ctx);
71a82e8c82SStefano Zampini 
72a82e8c82SStefano Zampini +  tao  - the Tao  context
73a82e8c82SStefano Zampini .  x    - input vector
74a82e8c82SStefano Zampini .  H    - Hessian matrix
75a82e8c82SStefano Zampini .  Hpre - preconditioner matrix, usually the same as H
76a82e8c82SStefano Zampini -  ctx  - [optional] user-defined Hessian context
77a82e8c82SStefano Zampini 
78a82e8c82SStefano Zampini    Level: beginner
79a82e8c82SStefano Zampini 
8065ba42b6SBarry Smith .seealso: `Tao`, TaoType`, `TaoGetObjective()`, `TaoGetGradient()`, `TaoGetObjectiveAndGradient()`, `TaoSetHessian()`
81a82e8c82SStefano Zampini @*/
829371c9d4SSatish Balay PetscErrorCode TaoGetHessian(Tao tao, Mat *H, Mat *Hpre, PetscErrorCode (**func)(Tao, Vec, Mat, Mat, void *), void **ctx) {
83a82e8c82SStefano Zampini   PetscFunctionBegin;
84a82e8c82SStefano Zampini   PetscValidHeaderSpecific(tao, TAO_CLASSID, 1);
85a82e8c82SStefano Zampini   if (H) *H = tao->hessian;
86a82e8c82SStefano Zampini   if (Hpre) *Hpre = tao->hessian_pre;
87a82e8c82SStefano Zampini   if (ctx) *ctx = tao->user_hessP;
88a82e8c82SStefano Zampini   if (func) *func = tao->ops->computehessian;
89a82e8c82SStefano Zampini   PetscFunctionReturn(0);
90a82e8c82SStefano Zampini }
91a82e8c82SStefano Zampini 
929371c9d4SSatish Balay PetscErrorCode TaoTestHessian(Tao tao) {
9309baa881SHong Zhang   Mat               A, B, C, D, hessian;
9409baa881SHong Zhang   Vec               x = tao->solution;
9509baa881SHong Zhang   PetscReal         nrm, gnorm;
9609baa881SHong Zhang   PetscReal         threshold = 1.e-5;
9709baa881SHong Zhang   PetscInt          m, n, M, N;
9809baa881SHong Zhang   PetscBool         complete_print = PETSC_FALSE, test = PETSC_FALSE, flg;
99f49d1c87SHong Zhang   PetscViewer       viewer, mviewer;
10009baa881SHong Zhang   MPI_Comm          comm;
10109baa881SHong Zhang   PetscInt          tabs;
10209baa881SHong Zhang   static PetscBool  directionsprinted = PETSC_FALSE;
103f49d1c87SHong Zhang   PetscViewerFormat format;
10409baa881SHong Zhang 
10509baa881SHong Zhang   PetscFunctionBegin;
106d0609cedSBarry Smith   PetscObjectOptionsBegin((PetscObject)tao);
1079566063dSJacob Faibussowitsch   PetscCall(PetscOptionsName("-tao_test_hessian", "Compare hand-coded and finite difference Hessians", "None", &test));
1089566063dSJacob Faibussowitsch   PetscCall(PetscOptionsReal("-tao_test_hessian", "Threshold for element difference between hand-coded and finite difference being meaningful", "None", threshold, &threshold, NULL));
1099566063dSJacob Faibussowitsch   PetscCall(PetscOptionsViewer("-tao_test_hessian_view", "View difference between hand-coded and finite difference Hessians element entries", "None", &mviewer, &format, &complete_print));
110d0609cedSBarry Smith   PetscOptionsEnd();
11109baa881SHong Zhang   if (!test) PetscFunctionReturn(0);
11209baa881SHong Zhang 
1139566063dSJacob Faibussowitsch   PetscCall(PetscObjectGetComm((PetscObject)tao, &comm));
1149566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIGetStdout(comm, &viewer));
1159566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIGetTab(viewer, &tabs));
1169566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIISetTab(viewer, ((PetscObject)tao)->tablevel));
1179566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPrintf(viewer, "  ---------- Testing Hessian -------------\n"));
11809baa881SHong Zhang   if (!complete_print && !directionsprinted) {
1199566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer, "  Run with -tao_test_hessian_view and optionally -tao_test_hessian <threshold> to show difference\n"));
1209566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer, "    of hand-coded and finite difference Hessian entries greater than <threshold>.\n"));
12109baa881SHong Zhang   }
12209baa881SHong Zhang   if (!directionsprinted) {
1239566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer, "  Testing hand-coded Hessian, if (for double precision runs) ||J - Jfd||_F/||J||_F is\n"));
1249566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer, "    O(1.e-8), the hand-coded Hessian is probably correct.\n"));
12509baa881SHong Zhang     directionsprinted = PETSC_TRUE;
12609baa881SHong Zhang   }
1271baa6e33SBarry Smith   if (complete_print) PetscCall(PetscViewerPushFormat(mviewer, format));
12809baa881SHong Zhang 
1299566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)tao->hessian, MATMFFD, &flg));
13009baa881SHong Zhang   if (!flg) hessian = tao->hessian;
13109baa881SHong Zhang   else hessian = tao->hessian_pre;
13209baa881SHong Zhang 
13309baa881SHong Zhang   while (hessian) {
1349566063dSJacob Faibussowitsch     PetscCall(PetscObjectBaseTypeCompareAny((PetscObject)hessian, &flg, MATSEQAIJ, MATMPIAIJ, MATSEQDENSE, MATMPIDENSE, MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPIBAIJ, ""));
13509baa881SHong Zhang     if (flg) {
13609baa881SHong Zhang       A = hessian;
1379566063dSJacob Faibussowitsch       PetscCall(PetscObjectReference((PetscObject)A));
13809baa881SHong Zhang     } else {
1399566063dSJacob Faibussowitsch       PetscCall(MatComputeOperator(hessian, MATAIJ, &A));
14009baa881SHong Zhang     }
14109baa881SHong Zhang 
1429566063dSJacob Faibussowitsch     PetscCall(MatCreate(PetscObjectComm((PetscObject)A), &B));
1439566063dSJacob Faibussowitsch     PetscCall(MatGetSize(A, &M, &N));
1449566063dSJacob Faibussowitsch     PetscCall(MatGetLocalSize(A, &m, &n));
1459566063dSJacob Faibussowitsch     PetscCall(MatSetSizes(B, m, n, M, N));
1469566063dSJacob Faibussowitsch     PetscCall(MatSetType(B, ((PetscObject)A)->type_name));
1479566063dSJacob Faibussowitsch     PetscCall(MatSetUp(B));
1489566063dSJacob Faibussowitsch     PetscCall(MatSetOption(B, MAT_NEW_NONZERO_ALLOCATION_ERR, PETSC_FALSE));
14909baa881SHong Zhang 
1509566063dSJacob Faibussowitsch     PetscCall(TaoDefaultComputeHessian(tao, x, B, B, NULL));
15109baa881SHong Zhang 
1529566063dSJacob Faibussowitsch     PetscCall(MatDuplicate(B, MAT_COPY_VALUES, &D));
1539566063dSJacob Faibussowitsch     PetscCall(MatAYPX(D, -1.0, A, DIFFERENT_NONZERO_PATTERN));
1549566063dSJacob Faibussowitsch     PetscCall(MatNorm(D, NORM_FROBENIUS, &nrm));
1559566063dSJacob Faibussowitsch     PetscCall(MatNorm(A, NORM_FROBENIUS, &gnorm));
1569566063dSJacob Faibussowitsch     PetscCall(MatDestroy(&D));
15709baa881SHong Zhang     if (!gnorm) gnorm = 1; /* just in case */
1589566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer, "  ||H - Hfd||_F/||H||_F = %g, ||H - Hfd||_F = %g\n", (double)(nrm / gnorm), (double)nrm));
15909baa881SHong Zhang 
16009baa881SHong Zhang     if (complete_print) {
1619566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer, "  Hand-coded Hessian ----------\n"));
1629566063dSJacob Faibussowitsch       PetscCall(MatView(A, mviewer));
1639566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer, "  Finite difference Hessian ----------\n"));
1649566063dSJacob Faibussowitsch       PetscCall(MatView(B, mviewer));
16509baa881SHong Zhang     }
16609baa881SHong Zhang 
16709baa881SHong Zhang     if (complete_print) {
16809baa881SHong Zhang       PetscInt           Istart, Iend, *ccols, bncols, cncols, j, row;
16909baa881SHong Zhang       PetscScalar       *cvals;
17009baa881SHong Zhang       const PetscInt    *bcols;
17109baa881SHong Zhang       const PetscScalar *bvals;
17209baa881SHong Zhang 
1739566063dSJacob Faibussowitsch       PetscCall(MatAYPX(B, -1.0, A, DIFFERENT_NONZERO_PATTERN));
1749566063dSJacob Faibussowitsch       PetscCall(MatCreate(PetscObjectComm((PetscObject)A), &C));
1759566063dSJacob Faibussowitsch       PetscCall(MatSetSizes(C, m, n, M, N));
1769566063dSJacob Faibussowitsch       PetscCall(MatSetType(C, ((PetscObject)A)->type_name));
1779566063dSJacob Faibussowitsch       PetscCall(MatSetUp(C));
1789566063dSJacob Faibussowitsch       PetscCall(MatSetOption(C, MAT_NEW_NONZERO_ALLOCATION_ERR, PETSC_FALSE));
1799566063dSJacob Faibussowitsch       PetscCall(MatGetOwnershipRange(B, &Istart, &Iend));
18009baa881SHong Zhang 
18109baa881SHong Zhang       for (row = Istart; row < Iend; row++) {
1829566063dSJacob Faibussowitsch         PetscCall(MatGetRow(B, row, &bncols, &bcols, &bvals));
1839566063dSJacob Faibussowitsch         PetscCall(PetscMalloc2(bncols, &ccols, bncols, &cvals));
18409baa881SHong Zhang         for (j = 0, cncols = 0; j < bncols; j++) {
18509baa881SHong Zhang           if (PetscAbsScalar(bvals[j]) > threshold) {
18609baa881SHong Zhang             ccols[cncols] = bcols[j];
18709baa881SHong Zhang             cvals[cncols] = bvals[j];
18809baa881SHong Zhang             cncols += 1;
18909baa881SHong Zhang           }
19009baa881SHong Zhang         }
191*48a46eb9SPierre Jolivet         if (cncols) PetscCall(MatSetValues(C, 1, &row, cncols, ccols, cvals, INSERT_VALUES));
1929566063dSJacob Faibussowitsch         PetscCall(MatRestoreRow(B, row, &bncols, &bcols, &bvals));
1939566063dSJacob Faibussowitsch         PetscCall(PetscFree2(ccols, cvals));
19409baa881SHong Zhang       }
1959566063dSJacob Faibussowitsch       PetscCall(MatAssemblyBegin(C, MAT_FINAL_ASSEMBLY));
1969566063dSJacob Faibussowitsch       PetscCall(MatAssemblyEnd(C, MAT_FINAL_ASSEMBLY));
1979566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer, "  Finite-difference minus hand-coded Hessian with tolerance %g ----------\n", (double)threshold));
1989566063dSJacob Faibussowitsch       PetscCall(MatView(C, mviewer));
1999566063dSJacob Faibussowitsch       PetscCall(MatDestroy(&C));
20009baa881SHong Zhang     }
2019566063dSJacob Faibussowitsch     PetscCall(MatDestroy(&A));
2029566063dSJacob Faibussowitsch     PetscCall(MatDestroy(&B));
20309baa881SHong Zhang 
20409baa881SHong Zhang     if (hessian != tao->hessian_pre) {
20509baa881SHong Zhang       hessian = tao->hessian_pre;
2069566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer, "  ---------- Testing Hessian for preconditioner -------------\n"));
20709baa881SHong Zhang     } else hessian = NULL;
20809baa881SHong Zhang   }
209f49d1c87SHong Zhang   if (complete_print) {
2109566063dSJacob Faibussowitsch     PetscCall(PetscViewerPopFormat(mviewer));
2119566063dSJacob Faibussowitsch     PetscCall(PetscViewerDestroy(&mviewer));
212f49d1c87SHong Zhang   }
2139566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIISetTab(viewer, tabs));
21409baa881SHong Zhang   PetscFunctionReturn(0);
21509baa881SHong Zhang }
21609baa881SHong Zhang 
217a7e14dcfSSatish Balay /*@C
218a7e14dcfSSatish Balay    TaoComputeHessian - Computes the Hessian matrix that has been
21965ba42b6SBarry Smith    set with `TaoSetHessian()`.
220a7e14dcfSSatish Balay 
22165ba42b6SBarry Smith    Collective on tao
222a7e14dcfSSatish Balay 
223a7e14dcfSSatish Balay    Input Parameters:
224f4c1ad5cSStefano Zampini +  tao - the Tao solver context
225f4c1ad5cSStefano Zampini -  X   - input vector
226a7e14dcfSSatish Balay 
227a7e14dcfSSatish Balay    Output Parameters:
228a7e14dcfSSatish Balay +  H    - Hessian matrix
229aa6c7ce3SBarry Smith -  Hpre - Preconditioning matrix
230a7e14dcfSSatish Balay 
23109baa881SHong Zhang    Options Database Keys:
23209baa881SHong Zhang +     -tao_test_hessian - compare the user provided Hessian with one compute via finite differences to check for errors
23309baa881SHong 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
234dfe02fe6SHong 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
23509baa881SHong Zhang 
236a7e14dcfSSatish Balay    Notes:
237a7e14dcfSSatish Balay    Most users should not need to explicitly call this routine, as it
238a7e14dcfSSatish Balay    is used internally within the minimization solvers.
239a7e14dcfSSatish Balay 
24065ba42b6SBarry Smith    `TaoComputeHessian()` is typically used within optimization algorithms,
24165ba42b6SBarry Smith    so most users would not generally call this routine
242a7e14dcfSSatish Balay    themselves.
243a7e14dcfSSatish Balay 
24465ba42b6SBarry Smith    Developer Note:
24565ba42b6SBarry Smith    The Hessian test mechanism follows `SNESTestJacobian()`.
24609baa881SHong Zhang 
247a7e14dcfSSatish Balay    Level: developer
248a7e14dcfSSatish Balay 
24965ba42b6SBarry Smith .seealso: `Tao`, `TaoComputeObjective()`, `TaoComputeObjectiveAndGradient()`, `TaoSetHessian()`
250a7e14dcfSSatish Balay @*/
2519371c9d4SSatish Balay PetscErrorCode TaoComputeHessian(Tao tao, Vec X, Mat H, Mat Hpre) {
252a7e14dcfSSatish Balay   PetscFunctionBegin;
253441846f8SBarry Smith   PetscValidHeaderSpecific(tao, TAO_CLASSID, 1);
254a7e14dcfSSatish Balay   PetscValidHeaderSpecific(X, VEC_CLASSID, 2);
255a7e14dcfSSatish Balay   PetscCheckSameComm(tao, 1, X, 2);
256a7e14dcfSSatish Balay   ++tao->nhess;
2579566063dSJacob Faibussowitsch   PetscCall(VecLockReadPush(X));
2589566063dSJacob Faibussowitsch   PetscCall(PetscLogEventBegin(TAO_HessianEval, tao, X, H, Hpre));
259792fecdfSBarry Smith   PetscCallBack("Tao callback Hessian", (*tao->ops->computehessian)(tao, X, H, Hpre, tao->user_hessP));
2609566063dSJacob Faibussowitsch   PetscCall(PetscLogEventEnd(TAO_HessianEval, tao, X, H, Hpre));
2619566063dSJacob Faibussowitsch   PetscCall(VecLockReadPop(X));
26209baa881SHong Zhang 
2639566063dSJacob Faibussowitsch   PetscCall(TaoTestHessian(tao));
264a7e14dcfSSatish Balay   PetscFunctionReturn(0);
265a7e14dcfSSatish Balay }
266a7e14dcfSSatish Balay 
267a7e14dcfSSatish Balay /*@C
268a7e14dcfSSatish Balay    TaoComputeJacobian - Computes the Jacobian matrix that has been
269a7e14dcfSSatish Balay    set with TaoSetJacobianRoutine().
270a7e14dcfSSatish Balay 
27165ba42b6SBarry Smith    Collective on tao
272a7e14dcfSSatish Balay 
273a7e14dcfSSatish Balay    Input Parameters:
274f4c1ad5cSStefano Zampini +  tao - the Tao solver context
275f4c1ad5cSStefano Zampini -  X   - input vector
276a7e14dcfSSatish Balay 
277a7e14dcfSSatish Balay    Output Parameters:
278f4c1ad5cSStefano Zampini +  J    - Jacobian matrix
279f4c1ad5cSStefano Zampini -  Jpre - Preconditioning matrix
280a7e14dcfSSatish Balay 
281a7e14dcfSSatish Balay    Notes:
282a7e14dcfSSatish Balay    Most users should not need to explicitly call this routine, as it
283a7e14dcfSSatish Balay    is used internally within the minimization solvers.
284a7e14dcfSSatish Balay 
28565ba42b6SBarry Smith    `TaoComputeJacobian()` is typically used within minimization
286a7e14dcfSSatish Balay    implementations, so most users would not generally call this routine
287a7e14dcfSSatish Balay    themselves.
288a7e14dcfSSatish Balay 
289a7e14dcfSSatish Balay    Level: developer
290a7e14dcfSSatish Balay 
291db781477SPatrick Sanan .seealso: `TaoComputeObjective()`, `TaoComputeObjectiveAndGradient()`, `TaoSetJacobianRoutine()`
292a7e14dcfSSatish Balay @*/
2939371c9d4SSatish Balay PetscErrorCode TaoComputeJacobian(Tao tao, Vec X, Mat J, Mat Jpre) {
294a7e14dcfSSatish Balay   PetscFunctionBegin;
295441846f8SBarry Smith   PetscValidHeaderSpecific(tao, TAO_CLASSID, 1);
296a7e14dcfSSatish Balay   PetscValidHeaderSpecific(X, VEC_CLASSID, 2);
297a7e14dcfSSatish Balay   PetscCheckSameComm(tao, 1, X, 2);
298a7e14dcfSSatish Balay   ++tao->njac;
2999566063dSJacob Faibussowitsch   PetscCall(VecLockReadPush(X));
3009566063dSJacob Faibussowitsch   PetscCall(PetscLogEventBegin(TAO_JacobianEval, tao, X, J, Jpre));
301792fecdfSBarry Smith   PetscCallBack("Tao callback Jacobian", (*tao->ops->computejacobian)(tao, X, J, Jpre, tao->user_jacP));
3029566063dSJacob Faibussowitsch   PetscCall(PetscLogEventEnd(TAO_JacobianEval, tao, X, J, Jpre));
3039566063dSJacob Faibussowitsch   PetscCall(VecLockReadPop(X));
304a7e14dcfSSatish Balay   PetscFunctionReturn(0);
305a7e14dcfSSatish Balay }
306a7e14dcfSSatish Balay 
307a7e14dcfSSatish Balay /*@C
3084a48860cSAlp Dener    TaoComputeResidualJacobian - Computes the least-squares residual Jacobian matrix that has been
30965ba42b6SBarry Smith    set with `TaoSetJacobianResidual()`.
3104a48860cSAlp Dener 
31165ba42b6SBarry Smith    Collective on tao
3124a48860cSAlp Dener 
3134a48860cSAlp Dener    Input Parameters:
3144a48860cSAlp Dener +  tao - the Tao solver context
3154a48860cSAlp Dener -  X   - input vector
3164a48860cSAlp Dener 
3174a48860cSAlp Dener    Output Parameters:
3184a48860cSAlp Dener +  J    - Jacobian matrix
3194a48860cSAlp Dener -  Jpre - Preconditioning matrix
3204a48860cSAlp Dener 
3214a48860cSAlp Dener    Notes:
3224a48860cSAlp Dener    Most users should not need to explicitly call this routine, as it
3234a48860cSAlp Dener    is used internally within the minimization solvers.
3244a48860cSAlp Dener 
32565ba42b6SBarry Smith    `TaoComputeResidualJacobian()` is typically used within least-squares
3264a48860cSAlp Dener    implementations, so most users would not generally call this routine
3274a48860cSAlp Dener    themselves.
3284a48860cSAlp Dener 
3294a48860cSAlp Dener    Level: developer
3304a48860cSAlp Dener 
33165ba42b6SBarry Smith .seealso: `Tao`, `TaoComputeResidual()`, `TaoSetJacobianResidual()`
3324a48860cSAlp Dener @*/
3339371c9d4SSatish Balay PetscErrorCode TaoComputeResidualJacobian(Tao tao, Vec X, Mat J, Mat Jpre) {
3344a48860cSAlp Dener   PetscFunctionBegin;
3354a48860cSAlp Dener   PetscValidHeaderSpecific(tao, TAO_CLASSID, 1);
3364a48860cSAlp Dener   PetscValidHeaderSpecific(X, VEC_CLASSID, 2);
3374a48860cSAlp Dener   PetscCheckSameComm(tao, 1, X, 2);
3384a48860cSAlp Dener   ++tao->njac;
3399566063dSJacob Faibussowitsch   PetscCall(VecLockReadPush(X));
3409566063dSJacob Faibussowitsch   PetscCall(PetscLogEventBegin(TAO_JacobianEval, tao, X, J, Jpre));
341792fecdfSBarry Smith   PetscCallBack("Tao callback least-squares residual Jacobian", (*tao->ops->computeresidualjacobian)(tao, X, J, Jpre, tao->user_lsjacP));
3429566063dSJacob Faibussowitsch   PetscCall(PetscLogEventEnd(TAO_JacobianEval, tao, X, J, Jpre));
3439566063dSJacob Faibussowitsch   PetscCall(VecLockReadPop(X));
3444a48860cSAlp Dener   PetscFunctionReturn(0);
3454a48860cSAlp Dener }
3464a48860cSAlp Dener 
3474a48860cSAlp Dener /*@C
348a7e14dcfSSatish Balay    TaoComputeJacobianState - Computes the Jacobian matrix that has been
34965ba42b6SBarry Smith    set with `TaoSetJacobianStateRoutine()`.
350a7e14dcfSSatish Balay 
35165ba42b6SBarry Smith    Collective on tao
352a7e14dcfSSatish Balay 
353a7e14dcfSSatish Balay    Input Parameters:
354f4c1ad5cSStefano Zampini +  tao - the Tao solver context
355f4c1ad5cSStefano Zampini -  X   - input vector
356a7e14dcfSSatish Balay 
357a7e14dcfSSatish Balay    Output Parameters:
3586b867d5aSJose E. Roman +  J    - Jacobian matrix
3596b867d5aSJose E. Roman .  Jpre - Preconditioning matrix
36065ba42b6SBarry Smith -  Jinv - unknown
361a7e14dcfSSatish Balay 
362a7e14dcfSSatish Balay    Notes:
363a7e14dcfSSatish Balay    Most users should not need to explicitly call this routine, as it
36465ba42b6SBarry Smith    is used internally within the optimization algorithms.
365a7e14dcfSSatish Balay 
366a7e14dcfSSatish Balay    Level: developer
367a7e14dcfSSatish Balay 
36865ba42b6SBarry Smith .seealso: `Tao`, `TaoComputeObjective()`, `TaoComputeObjectiveAndGradient()`, `TaoSetJacobianStateRoutine()`, `TaoComputeJacobianDesign()`, `TaoSetStateDesignIS()`
369a7e14dcfSSatish Balay @*/
3709371c9d4SSatish Balay PetscErrorCode TaoComputeJacobianState(Tao tao, Vec X, Mat J, Mat Jpre, Mat Jinv) {
371a7e14dcfSSatish Balay   PetscFunctionBegin;
372441846f8SBarry Smith   PetscValidHeaderSpecific(tao, TAO_CLASSID, 1);
373a7e14dcfSSatish Balay   PetscValidHeaderSpecific(X, VEC_CLASSID, 2);
374a7e14dcfSSatish Balay   PetscCheckSameComm(tao, 1, X, 2);
375a7e14dcfSSatish Balay   ++tao->njac_state;
3769566063dSJacob Faibussowitsch   PetscCall(VecLockReadPush(X));
3779566063dSJacob Faibussowitsch   PetscCall(PetscLogEventBegin(TAO_JacobianEval, tao, X, J, Jpre));
378792fecdfSBarry Smith   PetscCallBack("Tao callback Jacobian(state)", (*tao->ops->computejacobianstate)(tao, X, J, Jpre, Jinv, tao->user_jac_stateP));
3799566063dSJacob Faibussowitsch   PetscCall(PetscLogEventEnd(TAO_JacobianEval, tao, X, J, Jpre));
3809566063dSJacob Faibussowitsch   PetscCall(VecLockReadPop(X));
381a7e14dcfSSatish Balay   PetscFunctionReturn(0);
382a7e14dcfSSatish Balay }
383a7e14dcfSSatish Balay 
384a7e14dcfSSatish Balay /*@C
385a7e14dcfSSatish Balay    TaoComputeJacobianDesign - Computes the Jacobian matrix that has been
38665ba42b6SBarry Smith    set with `TaoSetJacobianDesignRoutine()`.
387a7e14dcfSSatish Balay 
38865ba42b6SBarry Smith    Collective on tao
389a7e14dcfSSatish Balay 
390a7e14dcfSSatish Balay    Input Parameters:
391f4c1ad5cSStefano Zampini +  tao - the Tao solver context
392f4c1ad5cSStefano Zampini -  X   - input vector
393a7e14dcfSSatish Balay 
394a7e14dcfSSatish Balay    Output Parameters:
395f4c1ad5cSStefano Zampini .  J - Jacobian matrix
396a7e14dcfSSatish Balay 
397a7e14dcfSSatish Balay    Notes:
398a7e14dcfSSatish Balay    Most users should not need to explicitly call this routine, as it
39965ba42b6SBarry Smith    is used internally within the optimization algorithms.
400a7e14dcfSSatish Balay 
401a7e14dcfSSatish Balay    Level: developer
402a7e14dcfSSatish Balay 
40365ba42b6SBarry Smith .seealso: `Tao`, `TaoComputeObjective()`, `TaoComputeObjectiveAndGradient()`, `TaoSetJacobianDesignRoutine()`, `TaoComputeJacobianDesign()`, `TaoSetStateDesignIS()`
404a7e14dcfSSatish Balay @*/
4059371c9d4SSatish Balay PetscErrorCode TaoComputeJacobianDesign(Tao tao, Vec X, Mat J) {
406a7e14dcfSSatish Balay   PetscFunctionBegin;
407441846f8SBarry Smith   PetscValidHeaderSpecific(tao, TAO_CLASSID, 1);
408a7e14dcfSSatish Balay   PetscValidHeaderSpecific(X, VEC_CLASSID, 2);
409a7e14dcfSSatish Balay   PetscCheckSameComm(tao, 1, X, 2);
410a7e14dcfSSatish Balay   ++tao->njac_design;
4119566063dSJacob Faibussowitsch   PetscCall(VecLockReadPush(X));
4129566063dSJacob Faibussowitsch   PetscCall(PetscLogEventBegin(TAO_JacobianEval, tao, X, J, NULL));
413792fecdfSBarry Smith   PetscCallBack("Tao callback Jacobian(design)", (*tao->ops->computejacobiandesign)(tao, X, J, tao->user_jac_designP));
4149566063dSJacob Faibussowitsch   PetscCall(PetscLogEventEnd(TAO_JacobianEval, tao, X, J, NULL));
4159566063dSJacob Faibussowitsch   PetscCall(VecLockReadPop(X));
416a7e14dcfSSatish Balay   PetscFunctionReturn(0);
417a7e14dcfSSatish Balay }
418a7e14dcfSSatish Balay 
419a7e14dcfSSatish Balay /*@C
420a7e14dcfSSatish Balay    TaoSetJacobianRoutine - Sets the function to compute the Jacobian as well as the location to store the matrix.
421a7e14dcfSSatish Balay 
42265ba42b6SBarry Smith    Logically collective on tao
423a7e14dcfSSatish Balay 
424a7e14dcfSSatish Balay    Input Parameters:
425441846f8SBarry Smith +  tao  - the Tao context
426a7e14dcfSSatish Balay .  J    - Matrix used for the jacobian
427a7e14dcfSSatish Balay .  Jpre - Matrix that will be used operated on by preconditioner, can be same as J
428f4c1ad5cSStefano Zampini .  func - Jacobian evaluation routine
429a7e14dcfSSatish Balay -  ctx  - [optional] user-defined context for private data for the
4306c23d075SBarry Smith           Jacobian evaluation routine (may be NULL)
431a7e14dcfSSatish Balay 
432f4c1ad5cSStefano Zampini    Calling sequence of func:
433f4c1ad5cSStefano Zampini $    func(Tao tao,Vec x,Mat J,Mat Jpre,void *ctx);
434a7e14dcfSSatish Balay 
435441846f8SBarry Smith +  tao  - the Tao  context
436a7e14dcfSSatish Balay .  x    - input vector
437a7e14dcfSSatish Balay .  J    - Jacobian matrix
438f4c1ad5cSStefano Zampini .  Jpre - preconditioning matrix, usually the same as J
439a7e14dcfSSatish Balay -  ctx  - [optional] user-defined Jacobian context
440a7e14dcfSSatish Balay 
441a7e14dcfSSatish Balay    Level: intermediate
44265ba42b6SBarry Smith 
44365ba42b6SBarry Smith .seealso: `Tao`, `TaoSetGradient()`, `TaoSetObjective()`
444a7e14dcfSSatish Balay @*/
4459371c9d4SSatish Balay PetscErrorCode TaoSetJacobianRoutine(Tao tao, Mat J, Mat Jpre, PetscErrorCode (*func)(Tao, Vec, Mat, Mat, void *), void *ctx) {
446a7e14dcfSSatish Balay   PetscFunctionBegin;
447441846f8SBarry Smith   PetscValidHeaderSpecific(tao, TAO_CLASSID, 1);
448a7e14dcfSSatish Balay   if (J) {
449a7e14dcfSSatish Balay     PetscValidHeaderSpecific(J, MAT_CLASSID, 2);
450a7e14dcfSSatish Balay     PetscCheckSameComm(tao, 1, J, 2);
451a7e14dcfSSatish Balay   }
452a7e14dcfSSatish Balay   if (Jpre) {
453a7e14dcfSSatish Balay     PetscValidHeaderSpecific(Jpre, MAT_CLASSID, 3);
454a7e14dcfSSatish Balay     PetscCheckSameComm(tao, 1, Jpre, 3);
455a7e14dcfSSatish Balay   }
4569371c9d4SSatish Balay   if (ctx) { tao->user_jacP = ctx; }
4579371c9d4SSatish Balay   if (func) { tao->ops->computejacobian = func; }
458a7e14dcfSSatish Balay   if (J) {
4599566063dSJacob Faibussowitsch     PetscCall(PetscObjectReference((PetscObject)J));
4609566063dSJacob Faibussowitsch     PetscCall(MatDestroy(&tao->jacobian));
461a7e14dcfSSatish Balay     tao->jacobian = J;
462a7e14dcfSSatish Balay   }
463a7e14dcfSSatish Balay   if (Jpre) {
4649566063dSJacob Faibussowitsch     PetscCall(PetscObjectReference((PetscObject)Jpre));
4659566063dSJacob Faibussowitsch     PetscCall(MatDestroy(&tao->jacobian_pre));
466a7e14dcfSSatish Balay     tao->jacobian_pre = Jpre;
467a7e14dcfSSatish Balay   }
468a7e14dcfSSatish Balay   PetscFunctionReturn(0);
469a7e14dcfSSatish Balay }
470a7e14dcfSSatish Balay 
471a7e14dcfSSatish Balay /*@C
4724ffbe8acSAlp Dener    TaoSetJacobianResidualRoutine - Sets the function to compute the least-squares residual Jacobian as well as the
4734a48860cSAlp Dener    location to store the matrix.
4744a48860cSAlp Dener 
47565ba42b6SBarry Smith    Logically collective on tao
4764a48860cSAlp Dener 
4774a48860cSAlp Dener    Input Parameters:
4784a48860cSAlp Dener +  tao  - the Tao context
4794a48860cSAlp Dener .  J    - Matrix used for the jacobian
4804a48860cSAlp Dener .  Jpre - Matrix that will be used operated on by preconditioner, can be same as J
4814a48860cSAlp Dener .  func - Jacobian evaluation routine
4824a48860cSAlp Dener -  ctx  - [optional] user-defined context for private data for the
4834a48860cSAlp Dener           Jacobian evaluation routine (may be NULL)
4844a48860cSAlp Dener 
4854a48860cSAlp Dener    Calling sequence of func:
4864a48860cSAlp Dener $    func(Tao tao,Vec x,Mat J,Mat Jpre,void *ctx);
4874a48860cSAlp Dener 
4884a48860cSAlp Dener +  tao  - the Tao  context
4894a48860cSAlp Dener .  x    - input vector
4904a48860cSAlp Dener .  J    - Jacobian matrix
4914a48860cSAlp Dener .  Jpre - preconditioning matrix, usually the same as J
4924a48860cSAlp Dener -  ctx  - [optional] user-defined Jacobian context
4934a48860cSAlp Dener 
4944a48860cSAlp Dener    Level: intermediate
49565ba42b6SBarry Smith 
49665ba42b6SBarry Smith .seealso: `Tao`, `TaoSetGradient()`, `TaoSetObjective()`
4974a48860cSAlp Dener @*/
4989371c9d4SSatish Balay PetscErrorCode TaoSetJacobianResidualRoutine(Tao tao, Mat J, Mat Jpre, PetscErrorCode (*func)(Tao, Vec, Mat, Mat, void *), void *ctx) {
4994a48860cSAlp Dener   PetscFunctionBegin;
5004a48860cSAlp Dener   PetscValidHeaderSpecific(tao, TAO_CLASSID, 1);
5014a48860cSAlp Dener   if (J) {
5024a48860cSAlp Dener     PetscValidHeaderSpecific(J, MAT_CLASSID, 2);
5034a48860cSAlp Dener     PetscCheckSameComm(tao, 1, J, 2);
5044a48860cSAlp Dener   }
5054a48860cSAlp Dener   if (Jpre) {
5064a48860cSAlp Dener     PetscValidHeaderSpecific(Jpre, MAT_CLASSID, 3);
5074a48860cSAlp Dener     PetscCheckSameComm(tao, 1, Jpre, 3);
5084a48860cSAlp Dener   }
5099371c9d4SSatish Balay   if (ctx) { tao->user_lsjacP = ctx; }
5109371c9d4SSatish Balay   if (func) { tao->ops->computeresidualjacobian = func; }
5114a48860cSAlp Dener   if (J) {
5129566063dSJacob Faibussowitsch     PetscCall(PetscObjectReference((PetscObject)J));
5139566063dSJacob Faibussowitsch     PetscCall(MatDestroy(&tao->ls_jac));
5144a48860cSAlp Dener     tao->ls_jac = J;
5154a48860cSAlp Dener   }
5164a48860cSAlp Dener   if (Jpre) {
5179566063dSJacob Faibussowitsch     PetscCall(PetscObjectReference((PetscObject)Jpre));
5189566063dSJacob Faibussowitsch     PetscCall(MatDestroy(&tao->ls_jac_pre));
5194a48860cSAlp Dener     tao->ls_jac_pre = Jpre;
5204a48860cSAlp Dener   }
5214a48860cSAlp Dener   PetscFunctionReturn(0);
5224a48860cSAlp Dener }
5234a48860cSAlp Dener 
5244a48860cSAlp Dener /*@C
525a7e14dcfSSatish Balay    TaoSetJacobianStateRoutine - Sets the function to compute the Jacobian
526a7e14dcfSSatish Balay    (and its inverse) of the constraint function with respect to the state variables.
52765ba42b6SBarry Smith    Used only for PDE-constrained optimization.
528a7e14dcfSSatish Balay 
52965ba42b6SBarry Smith    Logically collective on tao
530a7e14dcfSSatish Balay 
531a7e14dcfSSatish Balay    Input Parameters:
532441846f8SBarry Smith +  tao  - the Tao context
533a7e14dcfSSatish Balay .  J    - Matrix used for the jacobian
5346c23d075SBarry Smith .  Jpre - Matrix that will be used operated on by PETSc preconditioner, can be same as J.  Only used if Jinv is NULL
5356c23d075SBarry 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.
536f4c1ad5cSStefano Zampini .  func - Jacobian evaluation routine
537a7e14dcfSSatish Balay -  ctx  - [optional] user-defined context for private data for the
5386c23d075SBarry Smith           Jacobian evaluation routine (may be NULL)
539a7e14dcfSSatish Balay 
540f4c1ad5cSStefano Zampini    Calling sequence of func:
541f4c1ad5cSStefano Zampini $    func(Tao tao,Vec x,Mat J,Mat Jpre,Mat Jinv,void *ctx);
542a7e14dcfSSatish Balay 
543441846f8SBarry Smith +  tao  - the Tao  context
544a7e14dcfSSatish Balay .  x    - input vector
545a7e14dcfSSatish Balay .  J    - Jacobian matrix
546a7e14dcfSSatish Balay .  Jpre - preconditioner matrix, usually the same as J
547a7e14dcfSSatish Balay .  Jinv - inverse of J
548a7e14dcfSSatish Balay -  ctx  - [optional] user-defined Jacobian context
549a7e14dcfSSatish Balay 
550a7e14dcfSSatish Balay    Level: intermediate
55165ba42b6SBarry Smith 
55265ba42b6SBarry Smith .seealso: `Tao`, `TaoComputeJacobianState()`, `TaoSetJacobianDesignRoutine()`, `TaoSetStateDesignIS()`
553a7e14dcfSSatish Balay @*/
5549371c9d4SSatish Balay PetscErrorCode TaoSetJacobianStateRoutine(Tao tao, Mat J, Mat Jpre, Mat Jinv, PetscErrorCode (*func)(Tao, Vec, Mat, Mat, Mat, void *), void *ctx) {
555a7e14dcfSSatish Balay   PetscFunctionBegin;
556441846f8SBarry Smith   PetscValidHeaderSpecific(tao, TAO_CLASSID, 1);
557a7e14dcfSSatish Balay   if (J) {
558a7e14dcfSSatish Balay     PetscValidHeaderSpecific(J, MAT_CLASSID, 2);
559a7e14dcfSSatish Balay     PetscCheckSameComm(tao, 1, J, 2);
560a7e14dcfSSatish Balay   }
561a7e14dcfSSatish Balay   if (Jpre) {
562a7e14dcfSSatish Balay     PetscValidHeaderSpecific(Jpre, MAT_CLASSID, 3);
563a7e14dcfSSatish Balay     PetscCheckSameComm(tao, 1, Jpre, 3);
564a7e14dcfSSatish Balay   }
565a7e14dcfSSatish Balay   if (Jinv) {
566a7e14dcfSSatish Balay     PetscValidHeaderSpecific(Jinv, MAT_CLASSID, 4);
567a7e14dcfSSatish Balay     PetscCheckSameComm(tao, 1, Jinv, 4);
568a7e14dcfSSatish Balay   }
5699371c9d4SSatish Balay   if (ctx) { tao->user_jac_stateP = ctx; }
5709371c9d4SSatish Balay   if (func) { tao->ops->computejacobianstate = func; }
571a7e14dcfSSatish Balay   if (J) {
5729566063dSJacob Faibussowitsch     PetscCall(PetscObjectReference((PetscObject)J));
5739566063dSJacob Faibussowitsch     PetscCall(MatDestroy(&tao->jacobian_state));
574a7e14dcfSSatish Balay     tao->jacobian_state = J;
575a7e14dcfSSatish Balay   }
576a7e14dcfSSatish Balay   if (Jpre) {
5779566063dSJacob Faibussowitsch     PetscCall(PetscObjectReference((PetscObject)Jpre));
5789566063dSJacob Faibussowitsch     PetscCall(MatDestroy(&tao->jacobian_state_pre));
579a7e14dcfSSatish Balay     tao->jacobian_state_pre = Jpre;
580a7e14dcfSSatish Balay   }
581a7e14dcfSSatish Balay   if (Jinv) {
5829566063dSJacob Faibussowitsch     PetscCall(PetscObjectReference((PetscObject)Jinv));
5839566063dSJacob Faibussowitsch     PetscCall(MatDestroy(&tao->jacobian_state_inv));
584a7e14dcfSSatish Balay     tao->jacobian_state_inv = Jinv;
585a7e14dcfSSatish Balay   }
586a7e14dcfSSatish Balay   PetscFunctionReturn(0);
587a7e14dcfSSatish Balay }
588a7e14dcfSSatish Balay 
589a7e14dcfSSatish Balay /*@C
590a7e14dcfSSatish Balay    TaoSetJacobianDesignRoutine - Sets the function to compute the Jacobian of
591a7e14dcfSSatish Balay    the constraint function with respect to the design variables.  Used only for
59265ba42b6SBarry Smith    PDE-constrained optimization.
593a7e14dcfSSatish Balay 
59465ba42b6SBarry Smith    Logically collective on tao
595a7e14dcfSSatish Balay 
596a7e14dcfSSatish Balay    Input Parameters:
597441846f8SBarry Smith +  tao  - the Tao context
598a7e14dcfSSatish Balay .  J    - Matrix used for the jacobian
599f4c1ad5cSStefano Zampini .  func - Jacobian evaluation routine
600a7e14dcfSSatish Balay -  ctx  - [optional] user-defined context for private data for the
6016c23d075SBarry Smith           Jacobian evaluation routine (may be NULL)
602a7e14dcfSSatish Balay 
603f4c1ad5cSStefano Zampini    Calling sequence of func:
604f4c1ad5cSStefano Zampini $    func(Tao tao,Vec x,Mat J,void *ctx);
605a7e14dcfSSatish Balay 
606441846f8SBarry Smith +  tao - the Tao  context
607a7e14dcfSSatish Balay .  x   - input vector
608a7e14dcfSSatish Balay .  J   - Jacobian matrix
609a7e14dcfSSatish Balay -  ctx - [optional] user-defined Jacobian context
610a7e14dcfSSatish Balay 
611a7e14dcfSSatish Balay    Level: intermediate
612f4c1ad5cSStefano Zampini 
61365ba42b6SBarry Smith .seealso: `Tao`, `TaoComputeJacobianDesign()`, `TaoSetJacobianStateRoutine()`, `TaoSetStateDesignIS()`
614a7e14dcfSSatish Balay @*/
6159371c9d4SSatish Balay PetscErrorCode TaoSetJacobianDesignRoutine(Tao tao, Mat J, PetscErrorCode (*func)(Tao, Vec, Mat, void *), void *ctx) {
616a7e14dcfSSatish Balay   PetscFunctionBegin;
617441846f8SBarry Smith   PetscValidHeaderSpecific(tao, TAO_CLASSID, 1);
618a7e14dcfSSatish Balay   if (J) {
619a7e14dcfSSatish Balay     PetscValidHeaderSpecific(J, MAT_CLASSID, 2);
620a7e14dcfSSatish Balay     PetscCheckSameComm(tao, 1, J, 2);
621a7e14dcfSSatish Balay   }
6229371c9d4SSatish Balay   if (ctx) { tao->user_jac_designP = ctx; }
6239371c9d4SSatish Balay   if (func) { tao->ops->computejacobiandesign = func; }
624a7e14dcfSSatish Balay   if (J) {
6259566063dSJacob Faibussowitsch     PetscCall(PetscObjectReference((PetscObject)J));
6269566063dSJacob Faibussowitsch     PetscCall(MatDestroy(&tao->jacobian_design));
627a7e14dcfSSatish Balay     tao->jacobian_design = J;
628a7e14dcfSSatish Balay   }
629a7e14dcfSSatish Balay   PetscFunctionReturn(0);
630a7e14dcfSSatish Balay }
631a7e14dcfSSatish Balay 
632a7e14dcfSSatish Balay /*@
633441846f8SBarry Smith    TaoSetStateDesignIS - Indicate to the Tao which variables in the
634a7e14dcfSSatish Balay    solution vector are state variables and which are design.  Only applies to
63565ba42b6SBarry Smith    PDE-constrained optimization.
636a7e14dcfSSatish Balay 
637441846f8SBarry Smith    Logically Collective on Tao
638a7e14dcfSSatish Balay 
639a7e14dcfSSatish Balay    Input Parameters:
640441846f8SBarry Smith +  tao  - The Tao context
641a7e14dcfSSatish Balay .  s_is - the index set corresponding to the state variables
642a7e14dcfSSatish Balay -  d_is - the index set corresponding to the design variables
643a7e14dcfSSatish Balay 
644a7e14dcfSSatish Balay    Level: intermediate
645a7e14dcfSSatish Balay 
64665ba42b6SBarry Smith .seealso: `Tao`, `TaoSetJacobianStateRoutine()`, `TaoSetJacobianDesignRoutine()`
647a7e14dcfSSatish Balay @*/
6489371c9d4SSatish Balay PetscErrorCode TaoSetStateDesignIS(Tao tao, IS s_is, IS d_is) {
64945cf516eSBarry Smith   PetscFunctionBegin;
6509566063dSJacob Faibussowitsch   PetscCall(PetscObjectReference((PetscObject)s_is));
6519566063dSJacob Faibussowitsch   PetscCall(ISDestroy(&tao->state_is));
652a7e14dcfSSatish Balay   tao->state_is = s_is;
6539566063dSJacob Faibussowitsch   PetscCall(PetscObjectReference((PetscObject)(d_is)));
6549566063dSJacob Faibussowitsch   PetscCall(ISDestroy(&tao->design_is));
655a7e14dcfSSatish Balay   tao->design_is = d_is;
656a7e14dcfSSatish Balay   PetscFunctionReturn(0);
657a7e14dcfSSatish Balay }
658a7e14dcfSSatish Balay 
659a7e14dcfSSatish Balay /*@C
660a7e14dcfSSatish Balay    TaoComputeJacobianEquality - Computes the Jacobian matrix that has been
66165ba42b6SBarry Smith    set with `TaoSetJacobianEqualityRoutine()`.
662a7e14dcfSSatish Balay 
66365ba42b6SBarry Smith    Collective on tao
664a7e14dcfSSatish Balay 
665a7e14dcfSSatish Balay    Input Parameters:
666f4c1ad5cSStefano Zampini +  tao - the Tao solver context
667f4c1ad5cSStefano Zampini -  X   - input vector
668a7e14dcfSSatish Balay 
669a7e14dcfSSatish Balay    Output Parameters:
670f4c1ad5cSStefano Zampini +  J    - Jacobian matrix
671f4c1ad5cSStefano Zampini -  Jpre - Preconditioning matrix
672a7e14dcfSSatish Balay 
673a7e14dcfSSatish Balay    Notes:
674a7e14dcfSSatish Balay    Most users should not need to explicitly call this routine, as it
67565ba42b6SBarry Smith    is used internally within the optimization algorithms.
676a7e14dcfSSatish Balay 
677a7e14dcfSSatish Balay    Level: developer
678a7e14dcfSSatish Balay 
679db781477SPatrick Sanan .seealso: `TaoComputeObjective()`, `TaoComputeObjectiveAndGradient()`, `TaoSetJacobianStateRoutine()`, `TaoComputeJacobianDesign()`, `TaoSetStateDesignIS()`
680a7e14dcfSSatish Balay @*/
6819371c9d4SSatish Balay PetscErrorCode TaoComputeJacobianEquality(Tao tao, Vec X, Mat J, Mat Jpre) {
682a7e14dcfSSatish Balay   PetscFunctionBegin;
683441846f8SBarry Smith   PetscValidHeaderSpecific(tao, TAO_CLASSID, 1);
684a7e14dcfSSatish Balay   PetscValidHeaderSpecific(X, VEC_CLASSID, 2);
685a7e14dcfSSatish Balay   PetscCheckSameComm(tao, 1, X, 2);
686a7e14dcfSSatish Balay   ++tao->njac_equality;
6879566063dSJacob Faibussowitsch   PetscCall(VecLockReadPush(X));
6889566063dSJacob Faibussowitsch   PetscCall(PetscLogEventBegin(TAO_JacobianEval, tao, X, J, Jpre));
689792fecdfSBarry Smith   PetscCallBack("Tao callback Jacobian(equality)", (*tao->ops->computejacobianequality)(tao, X, J, Jpre, tao->user_jac_equalityP));
6909566063dSJacob Faibussowitsch   PetscCall(PetscLogEventEnd(TAO_JacobianEval, tao, X, J, Jpre));
6919566063dSJacob Faibussowitsch   PetscCall(VecLockReadPop(X));
692a7e14dcfSSatish Balay   PetscFunctionReturn(0);
693a7e14dcfSSatish Balay }
694a7e14dcfSSatish Balay 
695a7e14dcfSSatish Balay /*@C
696a7e14dcfSSatish Balay    TaoComputeJacobianInequality - Computes the Jacobian matrix that has been
69765ba42b6SBarry Smith    set with `TaoSetJacobianInequalityRoutine()`.
698a7e14dcfSSatish Balay 
69965ba42b6SBarry Smith    Collective on tao
700a7e14dcfSSatish Balay 
701a7e14dcfSSatish Balay    Input Parameters:
702f4c1ad5cSStefano Zampini +  tao - the Tao solver context
703f4c1ad5cSStefano Zampini -  X   - input vector
704a7e14dcfSSatish Balay 
705a7e14dcfSSatish Balay    Output Parameters:
706f4c1ad5cSStefano Zampini +  J    - Jacobian matrix
707f4c1ad5cSStefano Zampini -  Jpre - Preconditioning matrix
708a7e14dcfSSatish Balay 
709a7e14dcfSSatish Balay    Notes:
710a7e14dcfSSatish Balay    Most users should not need to explicitly call this routine, as it
711a7e14dcfSSatish Balay    is used internally within the minimization solvers.
712a7e14dcfSSatish Balay 
713a7e14dcfSSatish Balay    Level: developer
714a7e14dcfSSatish Balay 
71565ba42b6SBarry Smith .seealso: `Tao`, `TaoComputeObjective()`, `TaoComputeObjectiveAndGradient()`, `TaoSetJacobianStateRoutine()`, `TaoComputeJacobianDesign()`, `TaoSetStateDesignIS()`
716a7e14dcfSSatish Balay @*/
7179371c9d4SSatish Balay PetscErrorCode TaoComputeJacobianInequality(Tao tao, Vec X, Mat J, Mat Jpre) {
718a7e14dcfSSatish Balay   PetscFunctionBegin;
719441846f8SBarry Smith   PetscValidHeaderSpecific(tao, TAO_CLASSID, 1);
720a7e14dcfSSatish Balay   PetscValidHeaderSpecific(X, VEC_CLASSID, 2);
721a7e14dcfSSatish Balay   PetscCheckSameComm(tao, 1, X, 2);
722a7e14dcfSSatish Balay   ++tao->njac_inequality;
7239566063dSJacob Faibussowitsch   PetscCall(VecLockReadPush(X));
7249566063dSJacob Faibussowitsch   PetscCall(PetscLogEventBegin(TAO_JacobianEval, tao, X, J, Jpre));
725792fecdfSBarry Smith   PetscCallBack("Tao callback Jacobian (inequality)", (*tao->ops->computejacobianinequality)(tao, X, J, Jpre, tao->user_jac_inequalityP));
7269566063dSJacob Faibussowitsch   PetscCall(PetscLogEventEnd(TAO_JacobianEval, tao, X, J, Jpre));
7279566063dSJacob Faibussowitsch   PetscCall(VecLockReadPop(X));
728a7e14dcfSSatish Balay   PetscFunctionReturn(0);
729a7e14dcfSSatish Balay }
730a7e14dcfSSatish Balay 
731a7e14dcfSSatish Balay /*@C
732a7e14dcfSSatish Balay    TaoSetJacobianEqualityRoutine - Sets the function to compute the Jacobian
733a7e14dcfSSatish Balay    (and its inverse) of the constraint function with respect to the equality variables.
73465ba42b6SBarry Smith    Used only for PDE-constrained optimization.
735a7e14dcfSSatish Balay 
73665ba42b6SBarry Smith    Logically collective on tao
737a7e14dcfSSatish Balay 
738a7e14dcfSSatish Balay    Input Parameters:
739441846f8SBarry Smith +  tao  - the Tao context
740a7e14dcfSSatish Balay .  J    - Matrix used for the jacobian
741a7e14dcfSSatish Balay .  Jpre - Matrix that will be used operated on by PETSc preconditioner, can be same as J.
742f4c1ad5cSStefano Zampini .  func - Jacobian evaluation routine
743a7e14dcfSSatish Balay -  ctx  - [optional] user-defined context for private data for the
7446c23d075SBarry Smith           Jacobian evaluation routine (may be NULL)
745a7e14dcfSSatish Balay 
746f4c1ad5cSStefano Zampini    Calling sequence of func:
747f4c1ad5cSStefano Zampini $    func(Tao tao,Vec x,Mat J,Mat Jpre,void *ctx);
748a7e14dcfSSatish Balay 
749441846f8SBarry Smith +  tao  - the Tao  context
750a7e14dcfSSatish Balay .  x    - input vector
751a7e14dcfSSatish Balay .  J    - Jacobian matrix
752a7e14dcfSSatish Balay .  Jpre - preconditioner matrix, usually the same as J
753a7e14dcfSSatish Balay -  ctx  - [optional] user-defined Jacobian context
754a7e14dcfSSatish Balay 
755a7e14dcfSSatish Balay    Level: intermediate
756f4c1ad5cSStefano Zampini 
75765ba42b6SBarry Smith .seealso: `Tao`, `TaoComputeJacobianEquality()`, `TaoSetJacobianDesignRoutine()`, `TaoSetEqualityDesignIS()`
758a7e14dcfSSatish Balay @*/
7599371c9d4SSatish Balay PetscErrorCode TaoSetJacobianEqualityRoutine(Tao tao, Mat J, Mat Jpre, PetscErrorCode (*func)(Tao, Vec, Mat, Mat, void *), void *ctx) {
760a7e14dcfSSatish Balay   PetscFunctionBegin;
761441846f8SBarry Smith   PetscValidHeaderSpecific(tao, TAO_CLASSID, 1);
762a7e14dcfSSatish Balay   if (J) {
763a7e14dcfSSatish Balay     PetscValidHeaderSpecific(J, MAT_CLASSID, 2);
764a7e14dcfSSatish Balay     PetscCheckSameComm(tao, 1, J, 2);
765a7e14dcfSSatish Balay   }
766a7e14dcfSSatish Balay   if (Jpre) {
767a7e14dcfSSatish Balay     PetscValidHeaderSpecific(Jpre, MAT_CLASSID, 3);
768a7e14dcfSSatish Balay     PetscCheckSameComm(tao, 1, Jpre, 3);
769a7e14dcfSSatish Balay   }
7709371c9d4SSatish Balay   if (ctx) { tao->user_jac_equalityP = ctx; }
7719371c9d4SSatish Balay   if (func) { tao->ops->computejacobianequality = func; }
772a7e14dcfSSatish Balay   if (J) {
7739566063dSJacob Faibussowitsch     PetscCall(PetscObjectReference((PetscObject)J));
7749566063dSJacob Faibussowitsch     PetscCall(MatDestroy(&tao->jacobian_equality));
775a7e14dcfSSatish Balay     tao->jacobian_equality = J;
776a7e14dcfSSatish Balay   }
777a7e14dcfSSatish Balay   if (Jpre) {
7789566063dSJacob Faibussowitsch     PetscCall(PetscObjectReference((PetscObject)Jpre));
7799566063dSJacob Faibussowitsch     PetscCall(MatDestroy(&tao->jacobian_equality_pre));
780a7e14dcfSSatish Balay     tao->jacobian_equality_pre = Jpre;
781a7e14dcfSSatish Balay   }
782a7e14dcfSSatish Balay   PetscFunctionReturn(0);
783a7e14dcfSSatish Balay }
784a7e14dcfSSatish Balay 
785a7e14dcfSSatish Balay /*@C
786a7e14dcfSSatish Balay    TaoSetJacobianInequalityRoutine - Sets the function to compute the Jacobian
787a7e14dcfSSatish Balay    (and its inverse) of the constraint function with respect to the inequality variables.
78865ba42b6SBarry Smith    Used only for PDE-constrained optimization.
789a7e14dcfSSatish Balay 
79065ba42b6SBarry 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 
81165ba42b6SBarry Smith .seealso: `Tao`, `TaoComputeJacobianInequality()`, `TaoSetJacobianDesignRoutine()`, `TaoSetInequalityDesignIS()`
812a7e14dcfSSatish Balay @*/
8139371c9d4SSatish Balay PetscErrorCode TaoSetJacobianInequalityRoutine(Tao tao, Mat J, Mat Jpre, PetscErrorCode (*func)(Tao, Vec, Mat, Mat, void *), void *ctx) {
814a7e14dcfSSatish Balay   PetscFunctionBegin;
815441846f8SBarry Smith   PetscValidHeaderSpecific(tao, TAO_CLASSID, 1);
816a7e14dcfSSatish Balay   if (J) {
817a7e14dcfSSatish Balay     PetscValidHeaderSpecific(J, MAT_CLASSID, 2);
818a7e14dcfSSatish Balay     PetscCheckSameComm(tao, 1, J, 2);
819a7e14dcfSSatish Balay   }
820a7e14dcfSSatish Balay   if (Jpre) {
821a7e14dcfSSatish Balay     PetscValidHeaderSpecific(Jpre, MAT_CLASSID, 3);
822a7e14dcfSSatish Balay     PetscCheckSameComm(tao, 1, Jpre, 3);
823a7e14dcfSSatish Balay   }
8249371c9d4SSatish Balay   if (ctx) { tao->user_jac_inequalityP = ctx; }
8259371c9d4SSatish Balay   if (func) { tao->ops->computejacobianinequality = func; }
826a7e14dcfSSatish Balay   if (J) {
8279566063dSJacob Faibussowitsch     PetscCall(PetscObjectReference((PetscObject)J));
8289566063dSJacob Faibussowitsch     PetscCall(MatDestroy(&tao->jacobian_inequality));
829a7e14dcfSSatish Balay     tao->jacobian_inequality = J;
830a7e14dcfSSatish Balay   }
831a7e14dcfSSatish Balay   if (Jpre) {
8329566063dSJacob Faibussowitsch     PetscCall(PetscObjectReference((PetscObject)Jpre));
8339566063dSJacob Faibussowitsch     PetscCall(MatDestroy(&tao->jacobian_inequality_pre));
834a7e14dcfSSatish Balay     tao->jacobian_inequality_pre = Jpre;
835a7e14dcfSSatish Balay   }
836a7e14dcfSSatish Balay   PetscFunctionReturn(0);
837a7e14dcfSSatish Balay }
838