xref: /petsc/src/tao/interface/taosolver_hj.c (revision c3339decea92175325d9368fa13196bcd0e0e58b)
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*c3339decSBarry Smith    Logically collective
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 @*/
29d71ae5a4SJacob Faibussowitsch PetscErrorCode TaoSetHessian(Tao tao, Mat H, Mat Hpre, PetscErrorCode (*func)(Tao, Vec, Mat, Mat, void *), void *ctx)
30d71ae5a4SJacob Faibussowitsch {
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 
8165ba42b6SBarry Smith .seealso: `Tao`, TaoType`, `TaoGetObjective()`, `TaoGetGradient()`, `TaoGetObjectiveAndGradient()`, `TaoSetHessian()`
82a82e8c82SStefano Zampini @*/
83d71ae5a4SJacob Faibussowitsch PetscErrorCode TaoGetHessian(Tao tao, Mat *H, Mat *Hpre, PetscErrorCode (**func)(Tao, Vec, Mat, Mat, void *), void **ctx)
84d71ae5a4SJacob Faibussowitsch {
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 
94d71ae5a4SJacob Faibussowitsch PetscErrorCode TaoTestHessian(Tao tao)
95d71ae5a4SJacob Faibussowitsch {
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         }
19448a46eb9SPierre Jolivet         if (cncols) PetscCall(MatSetValues(C, 1, &row, cncols, ccols, cvals, INSERT_VALUES));
1959566063dSJacob Faibussowitsch         PetscCall(MatRestoreRow(B, row, &bncols, &bcols, &bvals));
1969566063dSJacob Faibussowitsch         PetscCall(PetscFree2(ccols, cvals));
19709baa881SHong Zhang       }
1989566063dSJacob Faibussowitsch       PetscCall(MatAssemblyBegin(C, MAT_FINAL_ASSEMBLY));
1999566063dSJacob Faibussowitsch       PetscCall(MatAssemblyEnd(C, MAT_FINAL_ASSEMBLY));
2009566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer, "  Finite-difference minus hand-coded Hessian with tolerance %g ----------\n", (double)threshold));
2019566063dSJacob Faibussowitsch       PetscCall(MatView(C, mviewer));
2029566063dSJacob Faibussowitsch       PetscCall(MatDestroy(&C));
20309baa881SHong Zhang     }
2049566063dSJacob Faibussowitsch     PetscCall(MatDestroy(&A));
2059566063dSJacob Faibussowitsch     PetscCall(MatDestroy(&B));
20609baa881SHong Zhang 
20709baa881SHong Zhang     if (hessian != tao->hessian_pre) {
20809baa881SHong Zhang       hessian = tao->hessian_pre;
2099566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer, "  ---------- Testing Hessian for preconditioner -------------\n"));
21009baa881SHong Zhang     } else hessian = NULL;
21109baa881SHong Zhang   }
212f49d1c87SHong Zhang   if (complete_print) {
2139566063dSJacob Faibussowitsch     PetscCall(PetscViewerPopFormat(mviewer));
2149566063dSJacob Faibussowitsch     PetscCall(PetscViewerDestroy(&mviewer));
215f49d1c87SHong Zhang   }
2169566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIISetTab(viewer, tabs));
21709baa881SHong Zhang   PetscFunctionReturn(0);
21809baa881SHong Zhang }
21909baa881SHong Zhang 
220a7e14dcfSSatish Balay /*@C
221a7e14dcfSSatish Balay    TaoComputeHessian - Computes the Hessian matrix that has been
22265ba42b6SBarry Smith    set with `TaoSetHessian()`.
223a7e14dcfSSatish Balay 
224*c3339decSBarry Smith    Collective
225a7e14dcfSSatish Balay 
226a7e14dcfSSatish Balay    Input Parameters:
227f4c1ad5cSStefano Zampini +  tao - the Tao solver context
228f4c1ad5cSStefano Zampini -  X   - input vector
229a7e14dcfSSatish Balay 
230a7e14dcfSSatish Balay    Output Parameters:
231a7e14dcfSSatish Balay +  H    - Hessian matrix
232aa6c7ce3SBarry Smith -  Hpre - Preconditioning matrix
233a7e14dcfSSatish Balay 
23409baa881SHong Zhang    Options Database Keys:
23509baa881SHong Zhang +     -tao_test_hessian - compare the user provided Hessian with one compute via finite differences to check for errors
23609baa881SHong 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
237dfe02fe6SHong 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
23809baa881SHong Zhang 
239a7e14dcfSSatish Balay    Notes:
240a7e14dcfSSatish Balay    Most users should not need to explicitly call this routine, as it
241a7e14dcfSSatish Balay    is used internally within the minimization solvers.
242a7e14dcfSSatish Balay 
24365ba42b6SBarry Smith    `TaoComputeHessian()` is typically used within optimization algorithms,
24465ba42b6SBarry Smith    so most users would not generally call this routine
245a7e14dcfSSatish Balay    themselves.
246a7e14dcfSSatish Balay 
24765ba42b6SBarry Smith    Developer Note:
24865ba42b6SBarry Smith    The Hessian test mechanism follows `SNESTestJacobian()`.
24909baa881SHong Zhang 
250a7e14dcfSSatish Balay    Level: developer
251a7e14dcfSSatish Balay 
25265ba42b6SBarry Smith .seealso: `Tao`, `TaoComputeObjective()`, `TaoComputeObjectiveAndGradient()`, `TaoSetHessian()`
253a7e14dcfSSatish Balay @*/
254d71ae5a4SJacob Faibussowitsch PetscErrorCode TaoComputeHessian(Tao tao, Vec X, Mat H, Mat Hpre)
255d71ae5a4SJacob Faibussowitsch {
256a7e14dcfSSatish Balay   PetscFunctionBegin;
257441846f8SBarry Smith   PetscValidHeaderSpecific(tao, TAO_CLASSID, 1);
258a7e14dcfSSatish Balay   PetscValidHeaderSpecific(X, VEC_CLASSID, 2);
259a7e14dcfSSatish Balay   PetscCheckSameComm(tao, 1, X, 2);
260794dad8cSStefano Zampini   PetscCheck(tao->ops->computehessian, PetscObjectComm((PetscObject)tao), PETSC_ERR_ARG_WRONGSTATE, "TaoSetHessian() not called");
261794dad8cSStefano Zampini 
262a7e14dcfSSatish Balay   ++tao->nhess;
2639566063dSJacob Faibussowitsch   PetscCall(VecLockReadPush(X));
2649566063dSJacob Faibussowitsch   PetscCall(PetscLogEventBegin(TAO_HessianEval, tao, X, H, Hpre));
265792fecdfSBarry Smith   PetscCallBack("Tao callback Hessian", (*tao->ops->computehessian)(tao, X, H, Hpre, tao->user_hessP));
2669566063dSJacob Faibussowitsch   PetscCall(PetscLogEventEnd(TAO_HessianEval, tao, X, H, Hpre));
2679566063dSJacob Faibussowitsch   PetscCall(VecLockReadPop(X));
26809baa881SHong Zhang 
2699566063dSJacob Faibussowitsch   PetscCall(TaoTestHessian(tao));
270a7e14dcfSSatish Balay   PetscFunctionReturn(0);
271a7e14dcfSSatish Balay }
272a7e14dcfSSatish Balay 
273a7e14dcfSSatish Balay /*@C
274a7e14dcfSSatish Balay    TaoComputeJacobian - Computes the Jacobian matrix that has been
275a7e14dcfSSatish Balay    set with TaoSetJacobianRoutine().
276a7e14dcfSSatish Balay 
277*c3339decSBarry Smith    Collective
278a7e14dcfSSatish Balay 
279a7e14dcfSSatish Balay    Input Parameters:
280f4c1ad5cSStefano Zampini +  tao - the Tao solver context
281f4c1ad5cSStefano Zampini -  X   - input vector
282a7e14dcfSSatish Balay 
283a7e14dcfSSatish Balay    Output Parameters:
284f4c1ad5cSStefano Zampini +  J    - Jacobian matrix
285f4c1ad5cSStefano Zampini -  Jpre - Preconditioning matrix
286a7e14dcfSSatish Balay 
287a7e14dcfSSatish Balay    Notes:
288a7e14dcfSSatish Balay    Most users should not need to explicitly call this routine, as it
289a7e14dcfSSatish Balay    is used internally within the minimization solvers.
290a7e14dcfSSatish Balay 
29165ba42b6SBarry Smith    `TaoComputeJacobian()` is typically used within minimization
292a7e14dcfSSatish Balay    implementations, so most users would not generally call this routine
293a7e14dcfSSatish Balay    themselves.
294a7e14dcfSSatish Balay 
295a7e14dcfSSatish Balay    Level: developer
296a7e14dcfSSatish Balay 
297db781477SPatrick Sanan .seealso: `TaoComputeObjective()`, `TaoComputeObjectiveAndGradient()`, `TaoSetJacobianRoutine()`
298a7e14dcfSSatish Balay @*/
299d71ae5a4SJacob Faibussowitsch PetscErrorCode TaoComputeJacobian(Tao tao, Vec X, Mat J, Mat Jpre)
300d71ae5a4SJacob Faibussowitsch {
301a7e14dcfSSatish Balay   PetscFunctionBegin;
302441846f8SBarry Smith   PetscValidHeaderSpecific(tao, TAO_CLASSID, 1);
303a7e14dcfSSatish Balay   PetscValidHeaderSpecific(X, VEC_CLASSID, 2);
304a7e14dcfSSatish Balay   PetscCheckSameComm(tao, 1, X, 2);
305a7e14dcfSSatish Balay   ++tao->njac;
3069566063dSJacob Faibussowitsch   PetscCall(VecLockReadPush(X));
3079566063dSJacob Faibussowitsch   PetscCall(PetscLogEventBegin(TAO_JacobianEval, tao, X, J, Jpre));
308792fecdfSBarry Smith   PetscCallBack("Tao callback Jacobian", (*tao->ops->computejacobian)(tao, X, J, Jpre, tao->user_jacP));
3099566063dSJacob Faibussowitsch   PetscCall(PetscLogEventEnd(TAO_JacobianEval, tao, X, J, Jpre));
3109566063dSJacob Faibussowitsch   PetscCall(VecLockReadPop(X));
311a7e14dcfSSatish Balay   PetscFunctionReturn(0);
312a7e14dcfSSatish Balay }
313a7e14dcfSSatish Balay 
314a7e14dcfSSatish Balay /*@C
3154a48860cSAlp Dener    TaoComputeResidualJacobian - Computes the least-squares residual Jacobian matrix that has been
31665ba42b6SBarry Smith    set with `TaoSetJacobianResidual()`.
3174a48860cSAlp Dener 
318*c3339decSBarry Smith    Collective
3194a48860cSAlp Dener 
3204a48860cSAlp Dener    Input Parameters:
3214a48860cSAlp Dener +  tao - the Tao solver context
3224a48860cSAlp Dener -  X   - input vector
3234a48860cSAlp Dener 
3244a48860cSAlp Dener    Output Parameters:
3254a48860cSAlp Dener +  J    - Jacobian matrix
3264a48860cSAlp Dener -  Jpre - Preconditioning matrix
3274a48860cSAlp Dener 
3284a48860cSAlp Dener    Notes:
3294a48860cSAlp Dener    Most users should not need to explicitly call this routine, as it
3304a48860cSAlp Dener    is used internally within the minimization solvers.
3314a48860cSAlp Dener 
33265ba42b6SBarry Smith    `TaoComputeResidualJacobian()` is typically used within least-squares
3334a48860cSAlp Dener    implementations, so most users would not generally call this routine
3344a48860cSAlp Dener    themselves.
3354a48860cSAlp Dener 
3364a48860cSAlp Dener    Level: developer
3374a48860cSAlp Dener 
33865ba42b6SBarry Smith .seealso: `Tao`, `TaoComputeResidual()`, `TaoSetJacobianResidual()`
3394a48860cSAlp Dener @*/
340d71ae5a4SJacob Faibussowitsch PetscErrorCode TaoComputeResidualJacobian(Tao tao, Vec X, Mat J, Mat Jpre)
341d71ae5a4SJacob Faibussowitsch {
3424a48860cSAlp Dener   PetscFunctionBegin;
3434a48860cSAlp Dener   PetscValidHeaderSpecific(tao, TAO_CLASSID, 1);
3444a48860cSAlp Dener   PetscValidHeaderSpecific(X, VEC_CLASSID, 2);
3454a48860cSAlp Dener   PetscCheckSameComm(tao, 1, X, 2);
3464a48860cSAlp Dener   ++tao->njac;
3479566063dSJacob Faibussowitsch   PetscCall(VecLockReadPush(X));
3489566063dSJacob Faibussowitsch   PetscCall(PetscLogEventBegin(TAO_JacobianEval, tao, X, J, Jpre));
349792fecdfSBarry Smith   PetscCallBack("Tao callback least-squares residual Jacobian", (*tao->ops->computeresidualjacobian)(tao, X, J, Jpre, tao->user_lsjacP));
3509566063dSJacob Faibussowitsch   PetscCall(PetscLogEventEnd(TAO_JacobianEval, tao, X, J, Jpre));
3519566063dSJacob Faibussowitsch   PetscCall(VecLockReadPop(X));
3524a48860cSAlp Dener   PetscFunctionReturn(0);
3534a48860cSAlp Dener }
3544a48860cSAlp Dener 
3554a48860cSAlp Dener /*@C
356a7e14dcfSSatish Balay    TaoComputeJacobianState - Computes the Jacobian matrix that has been
35765ba42b6SBarry Smith    set with `TaoSetJacobianStateRoutine()`.
358a7e14dcfSSatish Balay 
359*c3339decSBarry Smith    Collective
360a7e14dcfSSatish Balay 
361a7e14dcfSSatish Balay    Input Parameters:
362f4c1ad5cSStefano Zampini +  tao - the Tao solver context
363f4c1ad5cSStefano Zampini -  X   - input vector
364a7e14dcfSSatish Balay 
365a7e14dcfSSatish Balay    Output Parameters:
3666b867d5aSJose E. Roman +  J    - Jacobian matrix
3676b867d5aSJose E. Roman .  Jpre - Preconditioning matrix
36865ba42b6SBarry Smith -  Jinv - unknown
369a7e14dcfSSatish Balay 
370a7e14dcfSSatish Balay    Notes:
371a7e14dcfSSatish Balay    Most users should not need to explicitly call this routine, as it
37265ba42b6SBarry Smith    is used internally within the optimization algorithms.
373a7e14dcfSSatish Balay 
374a7e14dcfSSatish Balay    Level: developer
375a7e14dcfSSatish Balay 
37665ba42b6SBarry Smith .seealso: `Tao`, `TaoComputeObjective()`, `TaoComputeObjectiveAndGradient()`, `TaoSetJacobianStateRoutine()`, `TaoComputeJacobianDesign()`, `TaoSetStateDesignIS()`
377a7e14dcfSSatish Balay @*/
378d71ae5a4SJacob Faibussowitsch PetscErrorCode TaoComputeJacobianState(Tao tao, Vec X, Mat J, Mat Jpre, Mat Jinv)
379d71ae5a4SJacob Faibussowitsch {
380a7e14dcfSSatish Balay   PetscFunctionBegin;
381441846f8SBarry Smith   PetscValidHeaderSpecific(tao, TAO_CLASSID, 1);
382a7e14dcfSSatish Balay   PetscValidHeaderSpecific(X, VEC_CLASSID, 2);
383a7e14dcfSSatish Balay   PetscCheckSameComm(tao, 1, X, 2);
384a7e14dcfSSatish Balay   ++tao->njac_state;
3859566063dSJacob Faibussowitsch   PetscCall(VecLockReadPush(X));
3869566063dSJacob Faibussowitsch   PetscCall(PetscLogEventBegin(TAO_JacobianEval, tao, X, J, Jpre));
387792fecdfSBarry Smith   PetscCallBack("Tao callback Jacobian(state)", (*tao->ops->computejacobianstate)(tao, X, J, Jpre, Jinv, tao->user_jac_stateP));
3889566063dSJacob Faibussowitsch   PetscCall(PetscLogEventEnd(TAO_JacobianEval, tao, X, J, Jpre));
3899566063dSJacob Faibussowitsch   PetscCall(VecLockReadPop(X));
390a7e14dcfSSatish Balay   PetscFunctionReturn(0);
391a7e14dcfSSatish Balay }
392a7e14dcfSSatish Balay 
393a7e14dcfSSatish Balay /*@C
394a7e14dcfSSatish Balay    TaoComputeJacobianDesign - Computes the Jacobian matrix that has been
39565ba42b6SBarry Smith    set with `TaoSetJacobianDesignRoutine()`.
396a7e14dcfSSatish Balay 
397*c3339decSBarry Smith    Collective
398a7e14dcfSSatish Balay 
399a7e14dcfSSatish Balay    Input Parameters:
400f4c1ad5cSStefano Zampini +  tao - the Tao solver context
401f4c1ad5cSStefano Zampini -  X   - input vector
402a7e14dcfSSatish Balay 
403a7e14dcfSSatish Balay    Output Parameters:
404f4c1ad5cSStefano Zampini .  J - Jacobian matrix
405a7e14dcfSSatish Balay 
406a7e14dcfSSatish Balay    Notes:
407a7e14dcfSSatish Balay    Most users should not need to explicitly call this routine, as it
40865ba42b6SBarry Smith    is used internally within the optimization algorithms.
409a7e14dcfSSatish Balay 
410a7e14dcfSSatish Balay    Level: developer
411a7e14dcfSSatish Balay 
41265ba42b6SBarry Smith .seealso: `Tao`, `TaoComputeObjective()`, `TaoComputeObjectiveAndGradient()`, `TaoSetJacobianDesignRoutine()`, `TaoComputeJacobianDesign()`, `TaoSetStateDesignIS()`
413a7e14dcfSSatish Balay @*/
414d71ae5a4SJacob Faibussowitsch PetscErrorCode TaoComputeJacobianDesign(Tao tao, Vec X, Mat J)
415d71ae5a4SJacob Faibussowitsch {
416a7e14dcfSSatish Balay   PetscFunctionBegin;
417441846f8SBarry Smith   PetscValidHeaderSpecific(tao, TAO_CLASSID, 1);
418a7e14dcfSSatish Balay   PetscValidHeaderSpecific(X, VEC_CLASSID, 2);
419a7e14dcfSSatish Balay   PetscCheckSameComm(tao, 1, X, 2);
420a7e14dcfSSatish Balay   ++tao->njac_design;
4219566063dSJacob Faibussowitsch   PetscCall(VecLockReadPush(X));
4229566063dSJacob Faibussowitsch   PetscCall(PetscLogEventBegin(TAO_JacobianEval, tao, X, J, NULL));
423792fecdfSBarry Smith   PetscCallBack("Tao callback Jacobian(design)", (*tao->ops->computejacobiandesign)(tao, X, J, tao->user_jac_designP));
4249566063dSJacob Faibussowitsch   PetscCall(PetscLogEventEnd(TAO_JacobianEval, tao, X, J, NULL));
4259566063dSJacob Faibussowitsch   PetscCall(VecLockReadPop(X));
426a7e14dcfSSatish Balay   PetscFunctionReturn(0);
427a7e14dcfSSatish Balay }
428a7e14dcfSSatish Balay 
429a7e14dcfSSatish Balay /*@C
430a7e14dcfSSatish Balay    TaoSetJacobianRoutine - Sets the function to compute the Jacobian as well as the location to store the matrix.
431a7e14dcfSSatish Balay 
432*c3339decSBarry Smith    Logically collective
433a7e14dcfSSatish Balay 
434a7e14dcfSSatish Balay    Input Parameters:
435441846f8SBarry Smith +  tao  - the Tao context
436a7e14dcfSSatish Balay .  J    - Matrix used for the jacobian
437a7e14dcfSSatish Balay .  Jpre - Matrix that will be used operated on by preconditioner, can be same as J
438f4c1ad5cSStefano Zampini .  func - Jacobian evaluation routine
439a7e14dcfSSatish Balay -  ctx  - [optional] user-defined context for private data for the
4406c23d075SBarry Smith           Jacobian evaluation routine (may be NULL)
441a7e14dcfSSatish Balay 
442f4c1ad5cSStefano Zampini    Calling sequence of func:
443f4c1ad5cSStefano Zampini $    func(Tao tao,Vec x,Mat J,Mat Jpre,void *ctx);
444a7e14dcfSSatish Balay 
445441846f8SBarry Smith +  tao  - the Tao  context
446a7e14dcfSSatish Balay .  x    - input vector
447a7e14dcfSSatish Balay .  J    - Jacobian matrix
448f4c1ad5cSStefano Zampini .  Jpre - preconditioning matrix, usually the same as J
449a7e14dcfSSatish Balay -  ctx  - [optional] user-defined Jacobian context
450a7e14dcfSSatish Balay 
451a7e14dcfSSatish Balay    Level: intermediate
45265ba42b6SBarry Smith 
45365ba42b6SBarry Smith .seealso: `Tao`, `TaoSetGradient()`, `TaoSetObjective()`
454a7e14dcfSSatish Balay @*/
455d71ae5a4SJacob Faibussowitsch PetscErrorCode TaoSetJacobianRoutine(Tao tao, Mat J, Mat Jpre, PetscErrorCode (*func)(Tao, Vec, Mat, Mat, void *), void *ctx)
456d71ae5a4SJacob Faibussowitsch {
457a7e14dcfSSatish Balay   PetscFunctionBegin;
458441846f8SBarry Smith   PetscValidHeaderSpecific(tao, TAO_CLASSID, 1);
459a7e14dcfSSatish Balay   if (J) {
460a7e14dcfSSatish Balay     PetscValidHeaderSpecific(J, MAT_CLASSID, 2);
461a7e14dcfSSatish Balay     PetscCheckSameComm(tao, 1, J, 2);
462a7e14dcfSSatish Balay   }
463a7e14dcfSSatish Balay   if (Jpre) {
464a7e14dcfSSatish Balay     PetscValidHeaderSpecific(Jpre, MAT_CLASSID, 3);
465a7e14dcfSSatish Balay     PetscCheckSameComm(tao, 1, Jpre, 3);
466a7e14dcfSSatish Balay   }
467ad540459SPierre Jolivet   if (ctx) tao->user_jacP = ctx;
468ad540459SPierre Jolivet   if (func) tao->ops->computejacobian = func;
469a7e14dcfSSatish Balay   if (J) {
4709566063dSJacob Faibussowitsch     PetscCall(PetscObjectReference((PetscObject)J));
4719566063dSJacob Faibussowitsch     PetscCall(MatDestroy(&tao->jacobian));
472a7e14dcfSSatish Balay     tao->jacobian = J;
473a7e14dcfSSatish Balay   }
474a7e14dcfSSatish Balay   if (Jpre) {
4759566063dSJacob Faibussowitsch     PetscCall(PetscObjectReference((PetscObject)Jpre));
4769566063dSJacob Faibussowitsch     PetscCall(MatDestroy(&tao->jacobian_pre));
477a7e14dcfSSatish Balay     tao->jacobian_pre = Jpre;
478a7e14dcfSSatish Balay   }
479a7e14dcfSSatish Balay   PetscFunctionReturn(0);
480a7e14dcfSSatish Balay }
481a7e14dcfSSatish Balay 
482a7e14dcfSSatish Balay /*@C
4834ffbe8acSAlp Dener    TaoSetJacobianResidualRoutine - Sets the function to compute the least-squares residual Jacobian as well as the
4844a48860cSAlp Dener    location to store the matrix.
4854a48860cSAlp Dener 
486*c3339decSBarry Smith    Logically collective
4874a48860cSAlp Dener 
4884a48860cSAlp Dener    Input Parameters:
4894a48860cSAlp Dener +  tao  - the Tao context
4904a48860cSAlp Dener .  J    - Matrix used for the jacobian
4914a48860cSAlp Dener .  Jpre - Matrix that will be used operated on by preconditioner, can be same as J
4924a48860cSAlp Dener .  func - Jacobian evaluation routine
4934a48860cSAlp Dener -  ctx  - [optional] user-defined context for private data for the
4944a48860cSAlp Dener           Jacobian evaluation routine (may be NULL)
4954a48860cSAlp Dener 
4964a48860cSAlp Dener    Calling sequence of func:
4974a48860cSAlp Dener $    func(Tao tao,Vec x,Mat J,Mat Jpre,void *ctx);
4984a48860cSAlp Dener 
4994a48860cSAlp Dener +  tao  - the Tao  context
5004a48860cSAlp Dener .  x    - input vector
5014a48860cSAlp Dener .  J    - Jacobian matrix
5024a48860cSAlp Dener .  Jpre - preconditioning matrix, usually the same as J
5034a48860cSAlp Dener -  ctx  - [optional] user-defined Jacobian context
5044a48860cSAlp Dener 
5054a48860cSAlp Dener    Level: intermediate
50665ba42b6SBarry Smith 
50765ba42b6SBarry Smith .seealso: `Tao`, `TaoSetGradient()`, `TaoSetObjective()`
5084a48860cSAlp Dener @*/
509d71ae5a4SJacob Faibussowitsch PetscErrorCode TaoSetJacobianResidualRoutine(Tao tao, Mat J, Mat Jpre, PetscErrorCode (*func)(Tao, Vec, Mat, Mat, void *), void *ctx)
510d71ae5a4SJacob Faibussowitsch {
5114a48860cSAlp Dener   PetscFunctionBegin;
5124a48860cSAlp Dener   PetscValidHeaderSpecific(tao, TAO_CLASSID, 1);
5134a48860cSAlp Dener   if (J) {
5144a48860cSAlp Dener     PetscValidHeaderSpecific(J, MAT_CLASSID, 2);
5154a48860cSAlp Dener     PetscCheckSameComm(tao, 1, J, 2);
5164a48860cSAlp Dener   }
5174a48860cSAlp Dener   if (Jpre) {
5184a48860cSAlp Dener     PetscValidHeaderSpecific(Jpre, MAT_CLASSID, 3);
5194a48860cSAlp Dener     PetscCheckSameComm(tao, 1, Jpre, 3);
5204a48860cSAlp Dener   }
521ad540459SPierre Jolivet   if (ctx) tao->user_lsjacP = ctx;
522ad540459SPierre Jolivet   if (func) tao->ops->computeresidualjacobian = func;
5234a48860cSAlp Dener   if (J) {
5249566063dSJacob Faibussowitsch     PetscCall(PetscObjectReference((PetscObject)J));
5259566063dSJacob Faibussowitsch     PetscCall(MatDestroy(&tao->ls_jac));
5264a48860cSAlp Dener     tao->ls_jac = J;
5274a48860cSAlp Dener   }
5284a48860cSAlp Dener   if (Jpre) {
5299566063dSJacob Faibussowitsch     PetscCall(PetscObjectReference((PetscObject)Jpre));
5309566063dSJacob Faibussowitsch     PetscCall(MatDestroy(&tao->ls_jac_pre));
5314a48860cSAlp Dener     tao->ls_jac_pre = Jpre;
5324a48860cSAlp Dener   }
5334a48860cSAlp Dener   PetscFunctionReturn(0);
5344a48860cSAlp Dener }
5354a48860cSAlp Dener 
5364a48860cSAlp Dener /*@C
537a7e14dcfSSatish Balay    TaoSetJacobianStateRoutine - Sets the function to compute the Jacobian
538a7e14dcfSSatish Balay    (and its inverse) of the constraint function with respect to the state variables.
53965ba42b6SBarry Smith    Used only for PDE-constrained optimization.
540a7e14dcfSSatish Balay 
541*c3339decSBarry Smith    Logically collective
542a7e14dcfSSatish Balay 
543a7e14dcfSSatish Balay    Input Parameters:
544441846f8SBarry Smith +  tao  - the Tao context
545a7e14dcfSSatish Balay .  J    - Matrix used for the jacobian
5466c23d075SBarry Smith .  Jpre - Matrix that will be used operated on by PETSc preconditioner, can be same as J.  Only used if Jinv is NULL
5476c23d075SBarry 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.
548f4c1ad5cSStefano Zampini .  func - Jacobian evaluation routine
549a7e14dcfSSatish Balay -  ctx  - [optional] user-defined context for private data for the
5506c23d075SBarry Smith           Jacobian evaluation routine (may be NULL)
551a7e14dcfSSatish Balay 
552f4c1ad5cSStefano Zampini    Calling sequence of func:
553f4c1ad5cSStefano Zampini $    func(Tao tao,Vec x,Mat J,Mat Jpre,Mat Jinv,void *ctx);
554a7e14dcfSSatish Balay 
555441846f8SBarry Smith +  tao  - the Tao  context
556a7e14dcfSSatish Balay .  x    - input vector
557a7e14dcfSSatish Balay .  J    - Jacobian matrix
558a7e14dcfSSatish Balay .  Jpre - preconditioner matrix, usually the same as J
559a7e14dcfSSatish Balay .  Jinv - inverse of J
560a7e14dcfSSatish Balay -  ctx  - [optional] user-defined Jacobian context
561a7e14dcfSSatish Balay 
562a7e14dcfSSatish Balay    Level: intermediate
56365ba42b6SBarry Smith 
56465ba42b6SBarry Smith .seealso: `Tao`, `TaoComputeJacobianState()`, `TaoSetJacobianDesignRoutine()`, `TaoSetStateDesignIS()`
565a7e14dcfSSatish Balay @*/
566d71ae5a4SJacob Faibussowitsch PetscErrorCode TaoSetJacobianStateRoutine(Tao tao, Mat J, Mat Jpre, Mat Jinv, PetscErrorCode (*func)(Tao, Vec, Mat, Mat, Mat, void *), void *ctx)
567d71ae5a4SJacob Faibussowitsch {
568a7e14dcfSSatish Balay   PetscFunctionBegin;
569441846f8SBarry Smith   PetscValidHeaderSpecific(tao, TAO_CLASSID, 1);
570a7e14dcfSSatish Balay   if (J) {
571a7e14dcfSSatish Balay     PetscValidHeaderSpecific(J, MAT_CLASSID, 2);
572a7e14dcfSSatish Balay     PetscCheckSameComm(tao, 1, J, 2);
573a7e14dcfSSatish Balay   }
574a7e14dcfSSatish Balay   if (Jpre) {
575a7e14dcfSSatish Balay     PetscValidHeaderSpecific(Jpre, MAT_CLASSID, 3);
576a7e14dcfSSatish Balay     PetscCheckSameComm(tao, 1, Jpre, 3);
577a7e14dcfSSatish Balay   }
578a7e14dcfSSatish Balay   if (Jinv) {
579a7e14dcfSSatish Balay     PetscValidHeaderSpecific(Jinv, MAT_CLASSID, 4);
580a7e14dcfSSatish Balay     PetscCheckSameComm(tao, 1, Jinv, 4);
581a7e14dcfSSatish Balay   }
582ad540459SPierre Jolivet   if (ctx) tao->user_jac_stateP = ctx;
583ad540459SPierre Jolivet   if (func) tao->ops->computejacobianstate = func;
584a7e14dcfSSatish Balay   if (J) {
5859566063dSJacob Faibussowitsch     PetscCall(PetscObjectReference((PetscObject)J));
5869566063dSJacob Faibussowitsch     PetscCall(MatDestroy(&tao->jacobian_state));
587a7e14dcfSSatish Balay     tao->jacobian_state = J;
588a7e14dcfSSatish Balay   }
589a7e14dcfSSatish Balay   if (Jpre) {
5909566063dSJacob Faibussowitsch     PetscCall(PetscObjectReference((PetscObject)Jpre));
5919566063dSJacob Faibussowitsch     PetscCall(MatDestroy(&tao->jacobian_state_pre));
592a7e14dcfSSatish Balay     tao->jacobian_state_pre = Jpre;
593a7e14dcfSSatish Balay   }
594a7e14dcfSSatish Balay   if (Jinv) {
5959566063dSJacob Faibussowitsch     PetscCall(PetscObjectReference((PetscObject)Jinv));
5969566063dSJacob Faibussowitsch     PetscCall(MatDestroy(&tao->jacobian_state_inv));
597a7e14dcfSSatish Balay     tao->jacobian_state_inv = Jinv;
598a7e14dcfSSatish Balay   }
599a7e14dcfSSatish Balay   PetscFunctionReturn(0);
600a7e14dcfSSatish Balay }
601a7e14dcfSSatish Balay 
602a7e14dcfSSatish Balay /*@C
603a7e14dcfSSatish Balay    TaoSetJacobianDesignRoutine - Sets the function to compute the Jacobian of
604a7e14dcfSSatish Balay    the constraint function with respect to the design variables.  Used only for
60565ba42b6SBarry Smith    PDE-constrained optimization.
606a7e14dcfSSatish Balay 
607*c3339decSBarry Smith    Logically collective
608a7e14dcfSSatish Balay 
609a7e14dcfSSatish Balay    Input Parameters:
610441846f8SBarry Smith +  tao  - the Tao context
611a7e14dcfSSatish Balay .  J    - Matrix used for the jacobian
612f4c1ad5cSStefano Zampini .  func - Jacobian evaluation routine
613a7e14dcfSSatish Balay -  ctx  - [optional] user-defined context for private data for the
6146c23d075SBarry Smith           Jacobian evaluation routine (may be NULL)
615a7e14dcfSSatish Balay 
616f4c1ad5cSStefano Zampini    Calling sequence of func:
617f4c1ad5cSStefano Zampini $    func(Tao tao,Vec x,Mat J,void *ctx);
618a7e14dcfSSatish Balay 
619441846f8SBarry Smith +  tao - the Tao  context
620a7e14dcfSSatish Balay .  x   - input vector
621a7e14dcfSSatish Balay .  J   - Jacobian matrix
622a7e14dcfSSatish Balay -  ctx - [optional] user-defined Jacobian context
623a7e14dcfSSatish Balay 
624a7e14dcfSSatish Balay    Level: intermediate
625f4c1ad5cSStefano Zampini 
62665ba42b6SBarry Smith .seealso: `Tao`, `TaoComputeJacobianDesign()`, `TaoSetJacobianStateRoutine()`, `TaoSetStateDesignIS()`
627a7e14dcfSSatish Balay @*/
628d71ae5a4SJacob Faibussowitsch PetscErrorCode TaoSetJacobianDesignRoutine(Tao tao, Mat J, PetscErrorCode (*func)(Tao, Vec, Mat, void *), void *ctx)
629d71ae5a4SJacob Faibussowitsch {
630a7e14dcfSSatish Balay   PetscFunctionBegin;
631441846f8SBarry Smith   PetscValidHeaderSpecific(tao, TAO_CLASSID, 1);
632a7e14dcfSSatish Balay   if (J) {
633a7e14dcfSSatish Balay     PetscValidHeaderSpecific(J, MAT_CLASSID, 2);
634a7e14dcfSSatish Balay     PetscCheckSameComm(tao, 1, J, 2);
635a7e14dcfSSatish Balay   }
636ad540459SPierre Jolivet   if (ctx) tao->user_jac_designP = ctx;
637ad540459SPierre Jolivet   if (func) tao->ops->computejacobiandesign = func;
638a7e14dcfSSatish Balay   if (J) {
6399566063dSJacob Faibussowitsch     PetscCall(PetscObjectReference((PetscObject)J));
6409566063dSJacob Faibussowitsch     PetscCall(MatDestroy(&tao->jacobian_design));
641a7e14dcfSSatish Balay     tao->jacobian_design = J;
642a7e14dcfSSatish Balay   }
643a7e14dcfSSatish Balay   PetscFunctionReturn(0);
644a7e14dcfSSatish Balay }
645a7e14dcfSSatish Balay 
646a7e14dcfSSatish Balay /*@
647441846f8SBarry Smith    TaoSetStateDesignIS - Indicate to the Tao which variables in the
648a7e14dcfSSatish Balay    solution vector are state variables and which are design.  Only applies to
64965ba42b6SBarry Smith    PDE-constrained optimization.
650a7e14dcfSSatish Balay 
651*c3339decSBarry Smith    Logically Collective
652a7e14dcfSSatish Balay 
653a7e14dcfSSatish Balay    Input Parameters:
654441846f8SBarry Smith +  tao  - The Tao context
655a7e14dcfSSatish Balay .  s_is - the index set corresponding to the state variables
656a7e14dcfSSatish Balay -  d_is - the index set corresponding to the design variables
657a7e14dcfSSatish Balay 
658a7e14dcfSSatish Balay    Level: intermediate
659a7e14dcfSSatish Balay 
66065ba42b6SBarry Smith .seealso: `Tao`, `TaoSetJacobianStateRoutine()`, `TaoSetJacobianDesignRoutine()`
661a7e14dcfSSatish Balay @*/
662d71ae5a4SJacob Faibussowitsch PetscErrorCode TaoSetStateDesignIS(Tao tao, IS s_is, IS d_is)
663d71ae5a4SJacob Faibussowitsch {
66445cf516eSBarry Smith   PetscFunctionBegin;
6659566063dSJacob Faibussowitsch   PetscCall(PetscObjectReference((PetscObject)s_is));
6669566063dSJacob Faibussowitsch   PetscCall(ISDestroy(&tao->state_is));
667a7e14dcfSSatish Balay   tao->state_is = s_is;
6689566063dSJacob Faibussowitsch   PetscCall(PetscObjectReference((PetscObject)(d_is)));
6699566063dSJacob Faibussowitsch   PetscCall(ISDestroy(&tao->design_is));
670a7e14dcfSSatish Balay   tao->design_is = d_is;
671a7e14dcfSSatish Balay   PetscFunctionReturn(0);
672a7e14dcfSSatish Balay }
673a7e14dcfSSatish Balay 
674a7e14dcfSSatish Balay /*@C
675a7e14dcfSSatish Balay    TaoComputeJacobianEquality - Computes the Jacobian matrix that has been
67665ba42b6SBarry Smith    set with `TaoSetJacobianEqualityRoutine()`.
677a7e14dcfSSatish Balay 
678*c3339decSBarry Smith    Collective
679a7e14dcfSSatish Balay 
680a7e14dcfSSatish Balay    Input Parameters:
681f4c1ad5cSStefano Zampini +  tao - the Tao solver context
682f4c1ad5cSStefano Zampini -  X   - input vector
683a7e14dcfSSatish Balay 
684a7e14dcfSSatish Balay    Output Parameters:
685f4c1ad5cSStefano Zampini +  J    - Jacobian matrix
686f4c1ad5cSStefano Zampini -  Jpre - Preconditioning matrix
687a7e14dcfSSatish Balay 
688a7e14dcfSSatish Balay    Notes:
689a7e14dcfSSatish Balay    Most users should not need to explicitly call this routine, as it
69065ba42b6SBarry Smith    is used internally within the optimization algorithms.
691a7e14dcfSSatish Balay 
692a7e14dcfSSatish Balay    Level: developer
693a7e14dcfSSatish Balay 
694db781477SPatrick Sanan .seealso: `TaoComputeObjective()`, `TaoComputeObjectiveAndGradient()`, `TaoSetJacobianStateRoutine()`, `TaoComputeJacobianDesign()`, `TaoSetStateDesignIS()`
695a7e14dcfSSatish Balay @*/
696d71ae5a4SJacob Faibussowitsch PetscErrorCode TaoComputeJacobianEquality(Tao tao, Vec X, Mat J, Mat Jpre)
697d71ae5a4SJacob Faibussowitsch {
698a7e14dcfSSatish Balay   PetscFunctionBegin;
699441846f8SBarry Smith   PetscValidHeaderSpecific(tao, TAO_CLASSID, 1);
700a7e14dcfSSatish Balay   PetscValidHeaderSpecific(X, VEC_CLASSID, 2);
701a7e14dcfSSatish Balay   PetscCheckSameComm(tao, 1, X, 2);
702a7e14dcfSSatish Balay   ++tao->njac_equality;
7039566063dSJacob Faibussowitsch   PetscCall(VecLockReadPush(X));
7049566063dSJacob Faibussowitsch   PetscCall(PetscLogEventBegin(TAO_JacobianEval, tao, X, J, Jpre));
705792fecdfSBarry Smith   PetscCallBack("Tao callback Jacobian(equality)", (*tao->ops->computejacobianequality)(tao, X, J, Jpre, tao->user_jac_equalityP));
7069566063dSJacob Faibussowitsch   PetscCall(PetscLogEventEnd(TAO_JacobianEval, tao, X, J, Jpre));
7079566063dSJacob Faibussowitsch   PetscCall(VecLockReadPop(X));
708a7e14dcfSSatish Balay   PetscFunctionReturn(0);
709a7e14dcfSSatish Balay }
710a7e14dcfSSatish Balay 
711a7e14dcfSSatish Balay /*@C
712a7e14dcfSSatish Balay    TaoComputeJacobianInequality - Computes the Jacobian matrix that has been
71365ba42b6SBarry Smith    set with `TaoSetJacobianInequalityRoutine()`.
714a7e14dcfSSatish Balay 
715*c3339decSBarry Smith    Collective
716a7e14dcfSSatish Balay 
717a7e14dcfSSatish Balay    Input Parameters:
718f4c1ad5cSStefano Zampini +  tao - the Tao solver context
719f4c1ad5cSStefano Zampini -  X   - input vector
720a7e14dcfSSatish Balay 
721a7e14dcfSSatish Balay    Output Parameters:
722f4c1ad5cSStefano Zampini +  J    - Jacobian matrix
723f4c1ad5cSStefano Zampini -  Jpre - Preconditioning matrix
724a7e14dcfSSatish Balay 
725a7e14dcfSSatish Balay    Notes:
726a7e14dcfSSatish Balay    Most users should not need to explicitly call this routine, as it
727a7e14dcfSSatish Balay    is used internally within the minimization solvers.
728a7e14dcfSSatish Balay 
729a7e14dcfSSatish Balay    Level: developer
730a7e14dcfSSatish Balay 
73165ba42b6SBarry Smith .seealso: `Tao`, `TaoComputeObjective()`, `TaoComputeObjectiveAndGradient()`, `TaoSetJacobianStateRoutine()`, `TaoComputeJacobianDesign()`, `TaoSetStateDesignIS()`
732a7e14dcfSSatish Balay @*/
733d71ae5a4SJacob Faibussowitsch PetscErrorCode TaoComputeJacobianInequality(Tao tao, Vec X, Mat J, Mat Jpre)
734d71ae5a4SJacob Faibussowitsch {
735a7e14dcfSSatish Balay   PetscFunctionBegin;
736441846f8SBarry Smith   PetscValidHeaderSpecific(tao, TAO_CLASSID, 1);
737a7e14dcfSSatish Balay   PetscValidHeaderSpecific(X, VEC_CLASSID, 2);
738a7e14dcfSSatish Balay   PetscCheckSameComm(tao, 1, X, 2);
739a7e14dcfSSatish Balay   ++tao->njac_inequality;
7409566063dSJacob Faibussowitsch   PetscCall(VecLockReadPush(X));
7419566063dSJacob Faibussowitsch   PetscCall(PetscLogEventBegin(TAO_JacobianEval, tao, X, J, Jpre));
742792fecdfSBarry Smith   PetscCallBack("Tao callback Jacobian (inequality)", (*tao->ops->computejacobianinequality)(tao, X, J, Jpre, tao->user_jac_inequalityP));
7439566063dSJacob Faibussowitsch   PetscCall(PetscLogEventEnd(TAO_JacobianEval, tao, X, J, Jpre));
7449566063dSJacob Faibussowitsch   PetscCall(VecLockReadPop(X));
745a7e14dcfSSatish Balay   PetscFunctionReturn(0);
746a7e14dcfSSatish Balay }
747a7e14dcfSSatish Balay 
748a7e14dcfSSatish Balay /*@C
749a7e14dcfSSatish Balay    TaoSetJacobianEqualityRoutine - Sets the function to compute the Jacobian
750a7e14dcfSSatish Balay    (and its inverse) of the constraint function with respect to the equality variables.
75165ba42b6SBarry Smith    Used only for PDE-constrained optimization.
752a7e14dcfSSatish Balay 
753*c3339decSBarry Smith    Logically collective
754a7e14dcfSSatish Balay 
755a7e14dcfSSatish Balay    Input Parameters:
756441846f8SBarry Smith +  tao  - the Tao context
757a7e14dcfSSatish Balay .  J    - Matrix used for the jacobian
758a7e14dcfSSatish Balay .  Jpre - Matrix that will be used operated on by PETSc preconditioner, can be same as J.
759f4c1ad5cSStefano Zampini .  func - Jacobian evaluation routine
760a7e14dcfSSatish Balay -  ctx  - [optional] user-defined context for private data for the
7616c23d075SBarry Smith           Jacobian evaluation routine (may be NULL)
762a7e14dcfSSatish Balay 
763f4c1ad5cSStefano Zampini    Calling sequence of func:
764f4c1ad5cSStefano Zampini $    func(Tao tao,Vec x,Mat J,Mat Jpre,void *ctx);
765a7e14dcfSSatish Balay 
766441846f8SBarry Smith +  tao  - the Tao  context
767a7e14dcfSSatish Balay .  x    - input vector
768a7e14dcfSSatish Balay .  J    - Jacobian matrix
769a7e14dcfSSatish Balay .  Jpre - preconditioner matrix, usually the same as J
770a7e14dcfSSatish Balay -  ctx  - [optional] user-defined Jacobian context
771a7e14dcfSSatish Balay 
772a7e14dcfSSatish Balay    Level: intermediate
773f4c1ad5cSStefano Zampini 
77465ba42b6SBarry Smith .seealso: `Tao`, `TaoComputeJacobianEquality()`, `TaoSetJacobianDesignRoutine()`, `TaoSetEqualityDesignIS()`
775a7e14dcfSSatish Balay @*/
776d71ae5a4SJacob Faibussowitsch PetscErrorCode TaoSetJacobianEqualityRoutine(Tao tao, Mat J, Mat Jpre, PetscErrorCode (*func)(Tao, Vec, Mat, Mat, void *), void *ctx)
777d71ae5a4SJacob Faibussowitsch {
778a7e14dcfSSatish Balay   PetscFunctionBegin;
779441846f8SBarry Smith   PetscValidHeaderSpecific(tao, TAO_CLASSID, 1);
780a7e14dcfSSatish Balay   if (J) {
781a7e14dcfSSatish Balay     PetscValidHeaderSpecific(J, MAT_CLASSID, 2);
782a7e14dcfSSatish Balay     PetscCheckSameComm(tao, 1, J, 2);
783a7e14dcfSSatish Balay   }
784a7e14dcfSSatish Balay   if (Jpre) {
785a7e14dcfSSatish Balay     PetscValidHeaderSpecific(Jpre, MAT_CLASSID, 3);
786a7e14dcfSSatish Balay     PetscCheckSameComm(tao, 1, Jpre, 3);
787a7e14dcfSSatish Balay   }
788ad540459SPierre Jolivet   if (ctx) tao->user_jac_equalityP = ctx;
789ad540459SPierre Jolivet   if (func) tao->ops->computejacobianequality = func;
790a7e14dcfSSatish Balay   if (J) {
7919566063dSJacob Faibussowitsch     PetscCall(PetscObjectReference((PetscObject)J));
7929566063dSJacob Faibussowitsch     PetscCall(MatDestroy(&tao->jacobian_equality));
793a7e14dcfSSatish Balay     tao->jacobian_equality = J;
794a7e14dcfSSatish Balay   }
795a7e14dcfSSatish Balay   if (Jpre) {
7969566063dSJacob Faibussowitsch     PetscCall(PetscObjectReference((PetscObject)Jpre));
7979566063dSJacob Faibussowitsch     PetscCall(MatDestroy(&tao->jacobian_equality_pre));
798a7e14dcfSSatish Balay     tao->jacobian_equality_pre = Jpre;
799a7e14dcfSSatish Balay   }
800a7e14dcfSSatish Balay   PetscFunctionReturn(0);
801a7e14dcfSSatish Balay }
802a7e14dcfSSatish Balay 
803a7e14dcfSSatish Balay /*@C
804a7e14dcfSSatish Balay    TaoSetJacobianInequalityRoutine - Sets the function to compute the Jacobian
805a7e14dcfSSatish Balay    (and its inverse) of the constraint function with respect to the inequality variables.
80665ba42b6SBarry Smith    Used only for PDE-constrained optimization.
807a7e14dcfSSatish Balay 
808*c3339decSBarry Smith    Logically collective
809a7e14dcfSSatish Balay 
810a7e14dcfSSatish Balay    Input Parameters:
811441846f8SBarry Smith +  tao  - the Tao context
812a7e14dcfSSatish Balay .  J    - Matrix used for the jacobian
813a7e14dcfSSatish Balay .  Jpre - Matrix that will be used operated on by PETSc preconditioner, can be same as J.
814f4c1ad5cSStefano Zampini .  func - Jacobian evaluation routine
815a7e14dcfSSatish Balay -  ctx  - [optional] user-defined context for private data for the
8166c23d075SBarry Smith           Jacobian evaluation routine (may be NULL)
817a7e14dcfSSatish Balay 
818f4c1ad5cSStefano Zampini    Calling sequence of func:
819f4c1ad5cSStefano Zampini $    func(Tao tao,Vec x,Mat J,Mat Jpre,void *ctx);
820a7e14dcfSSatish Balay 
821441846f8SBarry Smith +  tao  - the Tao  context
822a7e14dcfSSatish Balay .  x    - input vector
823a7e14dcfSSatish Balay .  J    - Jacobian matrix
824a7e14dcfSSatish Balay .  Jpre - preconditioner matrix, usually the same as J
825a7e14dcfSSatish Balay -  ctx  - [optional] user-defined Jacobian context
826a7e14dcfSSatish Balay 
827a7e14dcfSSatish Balay    Level: intermediate
828f4c1ad5cSStefano Zampini 
82965ba42b6SBarry Smith .seealso: `Tao`, `TaoComputeJacobianInequality()`, `TaoSetJacobianDesignRoutine()`, `TaoSetInequalityDesignIS()`
830a7e14dcfSSatish Balay @*/
831d71ae5a4SJacob Faibussowitsch PetscErrorCode TaoSetJacobianInequalityRoutine(Tao tao, Mat J, Mat Jpre, PetscErrorCode (*func)(Tao, Vec, Mat, Mat, void *), void *ctx)
832d71ae5a4SJacob Faibussowitsch {
833a7e14dcfSSatish Balay   PetscFunctionBegin;
834441846f8SBarry Smith   PetscValidHeaderSpecific(tao, TAO_CLASSID, 1);
835a7e14dcfSSatish Balay   if (J) {
836a7e14dcfSSatish Balay     PetscValidHeaderSpecific(J, MAT_CLASSID, 2);
837a7e14dcfSSatish Balay     PetscCheckSameComm(tao, 1, J, 2);
838a7e14dcfSSatish Balay   }
839a7e14dcfSSatish Balay   if (Jpre) {
840a7e14dcfSSatish Balay     PetscValidHeaderSpecific(Jpre, MAT_CLASSID, 3);
841a7e14dcfSSatish Balay     PetscCheckSameComm(tao, 1, Jpre, 3);
842a7e14dcfSSatish Balay   }
843ad540459SPierre Jolivet   if (ctx) tao->user_jac_inequalityP = ctx;
844ad540459SPierre Jolivet   if (func) tao->ops->computejacobianinequality = func;
845a7e14dcfSSatish Balay   if (J) {
8469566063dSJacob Faibussowitsch     PetscCall(PetscObjectReference((PetscObject)J));
8479566063dSJacob Faibussowitsch     PetscCall(MatDestroy(&tao->jacobian_inequality));
848a7e14dcfSSatish Balay     tao->jacobian_inequality = J;
849a7e14dcfSSatish Balay   }
850a7e14dcfSSatish Balay   if (Jpre) {
8519566063dSJacob Faibussowitsch     PetscCall(PetscObjectReference((PetscObject)Jpre));
8529566063dSJacob Faibussowitsch     PetscCall(MatDestroy(&tao->jacobian_inequality_pre));
853a7e14dcfSSatish Balay     tao->jacobian_inequality_pre = Jpre;
854a7e14dcfSSatish Balay   }
855a7e14dcfSSatish Balay   PetscFunctionReturn(0);
856a7e14dcfSSatish Balay }
857