xref: /petsc/src/tao/interface/taosolver_hj.c (revision d71ae5a4db6382e7f06317b8d368875286fe9008)
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 @*/
29*d71ae5a4SJacob Faibussowitsch PetscErrorCode TaoSetHessian(Tao tao, Mat H, Mat Hpre, PetscErrorCode (*func)(Tao, Vec, Mat, Mat, void *), void *ctx)
30*d71ae5a4SJacob 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 @*/
83*d71ae5a4SJacob Faibussowitsch PetscErrorCode TaoGetHessian(Tao tao, Mat *H, Mat *Hpre, PetscErrorCode (**func)(Tao, Vec, Mat, Mat, void *), void **ctx)
84*d71ae5a4SJacob 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 
94*d71ae5a4SJacob Faibussowitsch PetscErrorCode TaoTestHessian(Tao tao)
95*d71ae5a4SJacob 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 
22465ba42b6SBarry Smith    Collective on tao
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 @*/
254*d71ae5a4SJacob Faibussowitsch PetscErrorCode TaoComputeHessian(Tao tao, Vec X, Mat H, Mat Hpre)
255*d71ae5a4SJacob 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);
260a7e14dcfSSatish Balay   ++tao->nhess;
2619566063dSJacob Faibussowitsch   PetscCall(VecLockReadPush(X));
2629566063dSJacob Faibussowitsch   PetscCall(PetscLogEventBegin(TAO_HessianEval, tao, X, H, Hpre));
263792fecdfSBarry Smith   PetscCallBack("Tao callback Hessian", (*tao->ops->computehessian)(tao, X, H, Hpre, tao->user_hessP));
2649566063dSJacob Faibussowitsch   PetscCall(PetscLogEventEnd(TAO_HessianEval, tao, X, H, Hpre));
2659566063dSJacob Faibussowitsch   PetscCall(VecLockReadPop(X));
26609baa881SHong Zhang 
2679566063dSJacob Faibussowitsch   PetscCall(TaoTestHessian(tao));
268a7e14dcfSSatish Balay   PetscFunctionReturn(0);
269a7e14dcfSSatish Balay }
270a7e14dcfSSatish Balay 
271a7e14dcfSSatish Balay /*@C
272a7e14dcfSSatish Balay    TaoComputeJacobian - Computes the Jacobian matrix that has been
273a7e14dcfSSatish Balay    set with TaoSetJacobianRoutine().
274a7e14dcfSSatish Balay 
27565ba42b6SBarry Smith    Collective on tao
276a7e14dcfSSatish Balay 
277a7e14dcfSSatish Balay    Input Parameters:
278f4c1ad5cSStefano Zampini +  tao - the Tao solver context
279f4c1ad5cSStefano Zampini -  X   - input vector
280a7e14dcfSSatish Balay 
281a7e14dcfSSatish Balay    Output Parameters:
282f4c1ad5cSStefano Zampini +  J    - Jacobian matrix
283f4c1ad5cSStefano Zampini -  Jpre - Preconditioning matrix
284a7e14dcfSSatish Balay 
285a7e14dcfSSatish Balay    Notes:
286a7e14dcfSSatish Balay    Most users should not need to explicitly call this routine, as it
287a7e14dcfSSatish Balay    is used internally within the minimization solvers.
288a7e14dcfSSatish Balay 
28965ba42b6SBarry Smith    `TaoComputeJacobian()` is typically used within minimization
290a7e14dcfSSatish Balay    implementations, so most users would not generally call this routine
291a7e14dcfSSatish Balay    themselves.
292a7e14dcfSSatish Balay 
293a7e14dcfSSatish Balay    Level: developer
294a7e14dcfSSatish Balay 
295db781477SPatrick Sanan .seealso: `TaoComputeObjective()`, `TaoComputeObjectiveAndGradient()`, `TaoSetJacobianRoutine()`
296a7e14dcfSSatish Balay @*/
297*d71ae5a4SJacob Faibussowitsch PetscErrorCode TaoComputeJacobian(Tao tao, Vec X, Mat J, Mat Jpre)
298*d71ae5a4SJacob Faibussowitsch {
299a7e14dcfSSatish Balay   PetscFunctionBegin;
300441846f8SBarry Smith   PetscValidHeaderSpecific(tao, TAO_CLASSID, 1);
301a7e14dcfSSatish Balay   PetscValidHeaderSpecific(X, VEC_CLASSID, 2);
302a7e14dcfSSatish Balay   PetscCheckSameComm(tao, 1, X, 2);
303a7e14dcfSSatish Balay   ++tao->njac;
3049566063dSJacob Faibussowitsch   PetscCall(VecLockReadPush(X));
3059566063dSJacob Faibussowitsch   PetscCall(PetscLogEventBegin(TAO_JacobianEval, tao, X, J, Jpre));
306792fecdfSBarry Smith   PetscCallBack("Tao callback Jacobian", (*tao->ops->computejacobian)(tao, X, J, Jpre, tao->user_jacP));
3079566063dSJacob Faibussowitsch   PetscCall(PetscLogEventEnd(TAO_JacobianEval, tao, X, J, Jpre));
3089566063dSJacob Faibussowitsch   PetscCall(VecLockReadPop(X));
309a7e14dcfSSatish Balay   PetscFunctionReturn(0);
310a7e14dcfSSatish Balay }
311a7e14dcfSSatish Balay 
312a7e14dcfSSatish Balay /*@C
3134a48860cSAlp Dener    TaoComputeResidualJacobian - Computes the least-squares residual Jacobian matrix that has been
31465ba42b6SBarry Smith    set with `TaoSetJacobianResidual()`.
3154a48860cSAlp Dener 
31665ba42b6SBarry Smith    Collective on tao
3174a48860cSAlp Dener 
3184a48860cSAlp Dener    Input Parameters:
3194a48860cSAlp Dener +  tao - the Tao solver context
3204a48860cSAlp Dener -  X   - input vector
3214a48860cSAlp Dener 
3224a48860cSAlp Dener    Output Parameters:
3234a48860cSAlp Dener +  J    - Jacobian matrix
3244a48860cSAlp Dener -  Jpre - Preconditioning matrix
3254a48860cSAlp Dener 
3264a48860cSAlp Dener    Notes:
3274a48860cSAlp Dener    Most users should not need to explicitly call this routine, as it
3284a48860cSAlp Dener    is used internally within the minimization solvers.
3294a48860cSAlp Dener 
33065ba42b6SBarry Smith    `TaoComputeResidualJacobian()` is typically used within least-squares
3314a48860cSAlp Dener    implementations, so most users would not generally call this routine
3324a48860cSAlp Dener    themselves.
3334a48860cSAlp Dener 
3344a48860cSAlp Dener    Level: developer
3354a48860cSAlp Dener 
33665ba42b6SBarry Smith .seealso: `Tao`, `TaoComputeResidual()`, `TaoSetJacobianResidual()`
3374a48860cSAlp Dener @*/
338*d71ae5a4SJacob Faibussowitsch PetscErrorCode TaoComputeResidualJacobian(Tao tao, Vec X, Mat J, Mat Jpre)
339*d71ae5a4SJacob Faibussowitsch {
3404a48860cSAlp Dener   PetscFunctionBegin;
3414a48860cSAlp Dener   PetscValidHeaderSpecific(tao, TAO_CLASSID, 1);
3424a48860cSAlp Dener   PetscValidHeaderSpecific(X, VEC_CLASSID, 2);
3434a48860cSAlp Dener   PetscCheckSameComm(tao, 1, X, 2);
3444a48860cSAlp Dener   ++tao->njac;
3459566063dSJacob Faibussowitsch   PetscCall(VecLockReadPush(X));
3469566063dSJacob Faibussowitsch   PetscCall(PetscLogEventBegin(TAO_JacobianEval, tao, X, J, Jpre));
347792fecdfSBarry Smith   PetscCallBack("Tao callback least-squares residual Jacobian", (*tao->ops->computeresidualjacobian)(tao, X, J, Jpre, tao->user_lsjacP));
3489566063dSJacob Faibussowitsch   PetscCall(PetscLogEventEnd(TAO_JacobianEval, tao, X, J, Jpre));
3499566063dSJacob Faibussowitsch   PetscCall(VecLockReadPop(X));
3504a48860cSAlp Dener   PetscFunctionReturn(0);
3514a48860cSAlp Dener }
3524a48860cSAlp Dener 
3534a48860cSAlp Dener /*@C
354a7e14dcfSSatish Balay    TaoComputeJacobianState - Computes the Jacobian matrix that has been
35565ba42b6SBarry Smith    set with `TaoSetJacobianStateRoutine()`.
356a7e14dcfSSatish Balay 
35765ba42b6SBarry Smith    Collective on tao
358a7e14dcfSSatish Balay 
359a7e14dcfSSatish Balay    Input Parameters:
360f4c1ad5cSStefano Zampini +  tao - the Tao solver context
361f4c1ad5cSStefano Zampini -  X   - input vector
362a7e14dcfSSatish Balay 
363a7e14dcfSSatish Balay    Output Parameters:
3646b867d5aSJose E. Roman +  J    - Jacobian matrix
3656b867d5aSJose E. Roman .  Jpre - Preconditioning matrix
36665ba42b6SBarry Smith -  Jinv - unknown
367a7e14dcfSSatish Balay 
368a7e14dcfSSatish Balay    Notes:
369a7e14dcfSSatish Balay    Most users should not need to explicitly call this routine, as it
37065ba42b6SBarry Smith    is used internally within the optimization algorithms.
371a7e14dcfSSatish Balay 
372a7e14dcfSSatish Balay    Level: developer
373a7e14dcfSSatish Balay 
37465ba42b6SBarry Smith .seealso: `Tao`, `TaoComputeObjective()`, `TaoComputeObjectiveAndGradient()`, `TaoSetJacobianStateRoutine()`, `TaoComputeJacobianDesign()`, `TaoSetStateDesignIS()`
375a7e14dcfSSatish Balay @*/
376*d71ae5a4SJacob Faibussowitsch PetscErrorCode TaoComputeJacobianState(Tao tao, Vec X, Mat J, Mat Jpre, Mat Jinv)
377*d71ae5a4SJacob Faibussowitsch {
378a7e14dcfSSatish Balay   PetscFunctionBegin;
379441846f8SBarry Smith   PetscValidHeaderSpecific(tao, TAO_CLASSID, 1);
380a7e14dcfSSatish Balay   PetscValidHeaderSpecific(X, VEC_CLASSID, 2);
381a7e14dcfSSatish Balay   PetscCheckSameComm(tao, 1, X, 2);
382a7e14dcfSSatish Balay   ++tao->njac_state;
3839566063dSJacob Faibussowitsch   PetscCall(VecLockReadPush(X));
3849566063dSJacob Faibussowitsch   PetscCall(PetscLogEventBegin(TAO_JacobianEval, tao, X, J, Jpre));
385792fecdfSBarry Smith   PetscCallBack("Tao callback Jacobian(state)", (*tao->ops->computejacobianstate)(tao, X, J, Jpre, Jinv, tao->user_jac_stateP));
3869566063dSJacob Faibussowitsch   PetscCall(PetscLogEventEnd(TAO_JacobianEval, tao, X, J, Jpre));
3879566063dSJacob Faibussowitsch   PetscCall(VecLockReadPop(X));
388a7e14dcfSSatish Balay   PetscFunctionReturn(0);
389a7e14dcfSSatish Balay }
390a7e14dcfSSatish Balay 
391a7e14dcfSSatish Balay /*@C
392a7e14dcfSSatish Balay    TaoComputeJacobianDesign - Computes the Jacobian matrix that has been
39365ba42b6SBarry Smith    set with `TaoSetJacobianDesignRoutine()`.
394a7e14dcfSSatish Balay 
39565ba42b6SBarry Smith    Collective on tao
396a7e14dcfSSatish Balay 
397a7e14dcfSSatish Balay    Input Parameters:
398f4c1ad5cSStefano Zampini +  tao - the Tao solver context
399f4c1ad5cSStefano Zampini -  X   - input vector
400a7e14dcfSSatish Balay 
401a7e14dcfSSatish Balay    Output Parameters:
402f4c1ad5cSStefano Zampini .  J - Jacobian matrix
403a7e14dcfSSatish Balay 
404a7e14dcfSSatish Balay    Notes:
405a7e14dcfSSatish Balay    Most users should not need to explicitly call this routine, as it
40665ba42b6SBarry Smith    is used internally within the optimization algorithms.
407a7e14dcfSSatish Balay 
408a7e14dcfSSatish Balay    Level: developer
409a7e14dcfSSatish Balay 
41065ba42b6SBarry Smith .seealso: `Tao`, `TaoComputeObjective()`, `TaoComputeObjectiveAndGradient()`, `TaoSetJacobianDesignRoutine()`, `TaoComputeJacobianDesign()`, `TaoSetStateDesignIS()`
411a7e14dcfSSatish Balay @*/
412*d71ae5a4SJacob Faibussowitsch PetscErrorCode TaoComputeJacobianDesign(Tao tao, Vec X, Mat J)
413*d71ae5a4SJacob Faibussowitsch {
414a7e14dcfSSatish Balay   PetscFunctionBegin;
415441846f8SBarry Smith   PetscValidHeaderSpecific(tao, TAO_CLASSID, 1);
416a7e14dcfSSatish Balay   PetscValidHeaderSpecific(X, VEC_CLASSID, 2);
417a7e14dcfSSatish Balay   PetscCheckSameComm(tao, 1, X, 2);
418a7e14dcfSSatish Balay   ++tao->njac_design;
4199566063dSJacob Faibussowitsch   PetscCall(VecLockReadPush(X));
4209566063dSJacob Faibussowitsch   PetscCall(PetscLogEventBegin(TAO_JacobianEval, tao, X, J, NULL));
421792fecdfSBarry Smith   PetscCallBack("Tao callback Jacobian(design)", (*tao->ops->computejacobiandesign)(tao, X, J, tao->user_jac_designP));
4229566063dSJacob Faibussowitsch   PetscCall(PetscLogEventEnd(TAO_JacobianEval, tao, X, J, NULL));
4239566063dSJacob Faibussowitsch   PetscCall(VecLockReadPop(X));
424a7e14dcfSSatish Balay   PetscFunctionReturn(0);
425a7e14dcfSSatish Balay }
426a7e14dcfSSatish Balay 
427a7e14dcfSSatish Balay /*@C
428a7e14dcfSSatish Balay    TaoSetJacobianRoutine - Sets the function to compute the Jacobian as well as the location to store the matrix.
429a7e14dcfSSatish Balay 
43065ba42b6SBarry Smith    Logically collective on tao
431a7e14dcfSSatish Balay 
432a7e14dcfSSatish Balay    Input Parameters:
433441846f8SBarry Smith +  tao  - the Tao context
434a7e14dcfSSatish Balay .  J    - Matrix used for the jacobian
435a7e14dcfSSatish Balay .  Jpre - Matrix that will be used operated on by preconditioner, can be same as J
436f4c1ad5cSStefano Zampini .  func - Jacobian evaluation routine
437a7e14dcfSSatish Balay -  ctx  - [optional] user-defined context for private data for the
4386c23d075SBarry Smith           Jacobian evaluation routine (may be NULL)
439a7e14dcfSSatish Balay 
440f4c1ad5cSStefano Zampini    Calling sequence of func:
441f4c1ad5cSStefano Zampini $    func(Tao tao,Vec x,Mat J,Mat Jpre,void *ctx);
442a7e14dcfSSatish Balay 
443441846f8SBarry Smith +  tao  - the Tao  context
444a7e14dcfSSatish Balay .  x    - input vector
445a7e14dcfSSatish Balay .  J    - Jacobian matrix
446f4c1ad5cSStefano Zampini .  Jpre - preconditioning matrix, usually the same as J
447a7e14dcfSSatish Balay -  ctx  - [optional] user-defined Jacobian context
448a7e14dcfSSatish Balay 
449a7e14dcfSSatish Balay    Level: intermediate
45065ba42b6SBarry Smith 
45165ba42b6SBarry Smith .seealso: `Tao`, `TaoSetGradient()`, `TaoSetObjective()`
452a7e14dcfSSatish Balay @*/
453*d71ae5a4SJacob Faibussowitsch PetscErrorCode TaoSetJacobianRoutine(Tao tao, Mat J, Mat Jpre, PetscErrorCode (*func)(Tao, Vec, Mat, Mat, void *), void *ctx)
454*d71ae5a4SJacob Faibussowitsch {
455a7e14dcfSSatish Balay   PetscFunctionBegin;
456441846f8SBarry Smith   PetscValidHeaderSpecific(tao, TAO_CLASSID, 1);
457a7e14dcfSSatish Balay   if (J) {
458a7e14dcfSSatish Balay     PetscValidHeaderSpecific(J, MAT_CLASSID, 2);
459a7e14dcfSSatish Balay     PetscCheckSameComm(tao, 1, J, 2);
460a7e14dcfSSatish Balay   }
461a7e14dcfSSatish Balay   if (Jpre) {
462a7e14dcfSSatish Balay     PetscValidHeaderSpecific(Jpre, MAT_CLASSID, 3);
463a7e14dcfSSatish Balay     PetscCheckSameComm(tao, 1, Jpre, 3);
464a7e14dcfSSatish Balay   }
465ad540459SPierre Jolivet   if (ctx) tao->user_jacP = ctx;
466ad540459SPierre Jolivet   if (func) tao->ops->computejacobian = func;
467a7e14dcfSSatish Balay   if (J) {
4689566063dSJacob Faibussowitsch     PetscCall(PetscObjectReference((PetscObject)J));
4699566063dSJacob Faibussowitsch     PetscCall(MatDestroy(&tao->jacobian));
470a7e14dcfSSatish Balay     tao->jacobian = J;
471a7e14dcfSSatish Balay   }
472a7e14dcfSSatish Balay   if (Jpre) {
4739566063dSJacob Faibussowitsch     PetscCall(PetscObjectReference((PetscObject)Jpre));
4749566063dSJacob Faibussowitsch     PetscCall(MatDestroy(&tao->jacobian_pre));
475a7e14dcfSSatish Balay     tao->jacobian_pre = Jpre;
476a7e14dcfSSatish Balay   }
477a7e14dcfSSatish Balay   PetscFunctionReturn(0);
478a7e14dcfSSatish Balay }
479a7e14dcfSSatish Balay 
480a7e14dcfSSatish Balay /*@C
4814ffbe8acSAlp Dener    TaoSetJacobianResidualRoutine - Sets the function to compute the least-squares residual Jacobian as well as the
4824a48860cSAlp Dener    location to store the matrix.
4834a48860cSAlp Dener 
48465ba42b6SBarry Smith    Logically collective on tao
4854a48860cSAlp Dener 
4864a48860cSAlp Dener    Input Parameters:
4874a48860cSAlp Dener +  tao  - the Tao context
4884a48860cSAlp Dener .  J    - Matrix used for the jacobian
4894a48860cSAlp Dener .  Jpre - Matrix that will be used operated on by preconditioner, can be same as J
4904a48860cSAlp Dener .  func - Jacobian evaluation routine
4914a48860cSAlp Dener -  ctx  - [optional] user-defined context for private data for the
4924a48860cSAlp Dener           Jacobian evaluation routine (may be NULL)
4934a48860cSAlp Dener 
4944a48860cSAlp Dener    Calling sequence of func:
4954a48860cSAlp Dener $    func(Tao tao,Vec x,Mat J,Mat Jpre,void *ctx);
4964a48860cSAlp Dener 
4974a48860cSAlp Dener +  tao  - the Tao  context
4984a48860cSAlp Dener .  x    - input vector
4994a48860cSAlp Dener .  J    - Jacobian matrix
5004a48860cSAlp Dener .  Jpre - preconditioning matrix, usually the same as J
5014a48860cSAlp Dener -  ctx  - [optional] user-defined Jacobian context
5024a48860cSAlp Dener 
5034a48860cSAlp Dener    Level: intermediate
50465ba42b6SBarry Smith 
50565ba42b6SBarry Smith .seealso: `Tao`, `TaoSetGradient()`, `TaoSetObjective()`
5064a48860cSAlp Dener @*/
507*d71ae5a4SJacob Faibussowitsch PetscErrorCode TaoSetJacobianResidualRoutine(Tao tao, Mat J, Mat Jpre, PetscErrorCode (*func)(Tao, Vec, Mat, Mat, void *), void *ctx)
508*d71ae5a4SJacob Faibussowitsch {
5094a48860cSAlp Dener   PetscFunctionBegin;
5104a48860cSAlp Dener   PetscValidHeaderSpecific(tao, TAO_CLASSID, 1);
5114a48860cSAlp Dener   if (J) {
5124a48860cSAlp Dener     PetscValidHeaderSpecific(J, MAT_CLASSID, 2);
5134a48860cSAlp Dener     PetscCheckSameComm(tao, 1, J, 2);
5144a48860cSAlp Dener   }
5154a48860cSAlp Dener   if (Jpre) {
5164a48860cSAlp Dener     PetscValidHeaderSpecific(Jpre, MAT_CLASSID, 3);
5174a48860cSAlp Dener     PetscCheckSameComm(tao, 1, Jpre, 3);
5184a48860cSAlp Dener   }
519ad540459SPierre Jolivet   if (ctx) tao->user_lsjacP = ctx;
520ad540459SPierre Jolivet   if (func) tao->ops->computeresidualjacobian = func;
5214a48860cSAlp Dener   if (J) {
5229566063dSJacob Faibussowitsch     PetscCall(PetscObjectReference((PetscObject)J));
5239566063dSJacob Faibussowitsch     PetscCall(MatDestroy(&tao->ls_jac));
5244a48860cSAlp Dener     tao->ls_jac = J;
5254a48860cSAlp Dener   }
5264a48860cSAlp Dener   if (Jpre) {
5279566063dSJacob Faibussowitsch     PetscCall(PetscObjectReference((PetscObject)Jpre));
5289566063dSJacob Faibussowitsch     PetscCall(MatDestroy(&tao->ls_jac_pre));
5294a48860cSAlp Dener     tao->ls_jac_pre = Jpre;
5304a48860cSAlp Dener   }
5314a48860cSAlp Dener   PetscFunctionReturn(0);
5324a48860cSAlp Dener }
5334a48860cSAlp Dener 
5344a48860cSAlp Dener /*@C
535a7e14dcfSSatish Balay    TaoSetJacobianStateRoutine - Sets the function to compute the Jacobian
536a7e14dcfSSatish Balay    (and its inverse) of the constraint function with respect to the state variables.
53765ba42b6SBarry Smith    Used only for PDE-constrained optimization.
538a7e14dcfSSatish Balay 
53965ba42b6SBarry Smith    Logically collective on tao
540a7e14dcfSSatish Balay 
541a7e14dcfSSatish Balay    Input Parameters:
542441846f8SBarry Smith +  tao  - the Tao context
543a7e14dcfSSatish Balay .  J    - Matrix used for the jacobian
5446c23d075SBarry Smith .  Jpre - Matrix that will be used operated on by PETSc preconditioner, can be same as J.  Only used if Jinv is NULL
5456c23d075SBarry 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.
546f4c1ad5cSStefano Zampini .  func - Jacobian evaluation routine
547a7e14dcfSSatish Balay -  ctx  - [optional] user-defined context for private data for the
5486c23d075SBarry Smith           Jacobian evaluation routine (may be NULL)
549a7e14dcfSSatish Balay 
550f4c1ad5cSStefano Zampini    Calling sequence of func:
551f4c1ad5cSStefano Zampini $    func(Tao tao,Vec x,Mat J,Mat Jpre,Mat Jinv,void *ctx);
552a7e14dcfSSatish Balay 
553441846f8SBarry Smith +  tao  - the Tao  context
554a7e14dcfSSatish Balay .  x    - input vector
555a7e14dcfSSatish Balay .  J    - Jacobian matrix
556a7e14dcfSSatish Balay .  Jpre - preconditioner matrix, usually the same as J
557a7e14dcfSSatish Balay .  Jinv - inverse of J
558a7e14dcfSSatish Balay -  ctx  - [optional] user-defined Jacobian context
559a7e14dcfSSatish Balay 
560a7e14dcfSSatish Balay    Level: intermediate
56165ba42b6SBarry Smith 
56265ba42b6SBarry Smith .seealso: `Tao`, `TaoComputeJacobianState()`, `TaoSetJacobianDesignRoutine()`, `TaoSetStateDesignIS()`
563a7e14dcfSSatish Balay @*/
564*d71ae5a4SJacob Faibussowitsch PetscErrorCode TaoSetJacobianStateRoutine(Tao tao, Mat J, Mat Jpre, Mat Jinv, PetscErrorCode (*func)(Tao, Vec, Mat, Mat, Mat, void *), void *ctx)
565*d71ae5a4SJacob Faibussowitsch {
566a7e14dcfSSatish Balay   PetscFunctionBegin;
567441846f8SBarry Smith   PetscValidHeaderSpecific(tao, TAO_CLASSID, 1);
568a7e14dcfSSatish Balay   if (J) {
569a7e14dcfSSatish Balay     PetscValidHeaderSpecific(J, MAT_CLASSID, 2);
570a7e14dcfSSatish Balay     PetscCheckSameComm(tao, 1, J, 2);
571a7e14dcfSSatish Balay   }
572a7e14dcfSSatish Balay   if (Jpre) {
573a7e14dcfSSatish Balay     PetscValidHeaderSpecific(Jpre, MAT_CLASSID, 3);
574a7e14dcfSSatish Balay     PetscCheckSameComm(tao, 1, Jpre, 3);
575a7e14dcfSSatish Balay   }
576a7e14dcfSSatish Balay   if (Jinv) {
577a7e14dcfSSatish Balay     PetscValidHeaderSpecific(Jinv, MAT_CLASSID, 4);
578a7e14dcfSSatish Balay     PetscCheckSameComm(tao, 1, Jinv, 4);
579a7e14dcfSSatish Balay   }
580ad540459SPierre Jolivet   if (ctx) tao->user_jac_stateP = ctx;
581ad540459SPierre Jolivet   if (func) tao->ops->computejacobianstate = func;
582a7e14dcfSSatish Balay   if (J) {
5839566063dSJacob Faibussowitsch     PetscCall(PetscObjectReference((PetscObject)J));
5849566063dSJacob Faibussowitsch     PetscCall(MatDestroy(&tao->jacobian_state));
585a7e14dcfSSatish Balay     tao->jacobian_state = J;
586a7e14dcfSSatish Balay   }
587a7e14dcfSSatish Balay   if (Jpre) {
5889566063dSJacob Faibussowitsch     PetscCall(PetscObjectReference((PetscObject)Jpre));
5899566063dSJacob Faibussowitsch     PetscCall(MatDestroy(&tao->jacobian_state_pre));
590a7e14dcfSSatish Balay     tao->jacobian_state_pre = Jpre;
591a7e14dcfSSatish Balay   }
592a7e14dcfSSatish Balay   if (Jinv) {
5939566063dSJacob Faibussowitsch     PetscCall(PetscObjectReference((PetscObject)Jinv));
5949566063dSJacob Faibussowitsch     PetscCall(MatDestroy(&tao->jacobian_state_inv));
595a7e14dcfSSatish Balay     tao->jacobian_state_inv = Jinv;
596a7e14dcfSSatish Balay   }
597a7e14dcfSSatish Balay   PetscFunctionReturn(0);
598a7e14dcfSSatish Balay }
599a7e14dcfSSatish Balay 
600a7e14dcfSSatish Balay /*@C
601a7e14dcfSSatish Balay    TaoSetJacobianDesignRoutine - Sets the function to compute the Jacobian of
602a7e14dcfSSatish Balay    the constraint function with respect to the design variables.  Used only for
60365ba42b6SBarry Smith    PDE-constrained optimization.
604a7e14dcfSSatish Balay 
60565ba42b6SBarry Smith    Logically collective on tao
606a7e14dcfSSatish Balay 
607a7e14dcfSSatish Balay    Input Parameters:
608441846f8SBarry Smith +  tao  - the Tao context
609a7e14dcfSSatish Balay .  J    - Matrix used for the jacobian
610f4c1ad5cSStefano Zampini .  func - Jacobian evaluation routine
611a7e14dcfSSatish Balay -  ctx  - [optional] user-defined context for private data for the
6126c23d075SBarry Smith           Jacobian evaluation routine (may be NULL)
613a7e14dcfSSatish Balay 
614f4c1ad5cSStefano Zampini    Calling sequence of func:
615f4c1ad5cSStefano Zampini $    func(Tao tao,Vec x,Mat J,void *ctx);
616a7e14dcfSSatish Balay 
617441846f8SBarry Smith +  tao - the Tao  context
618a7e14dcfSSatish Balay .  x   - input vector
619a7e14dcfSSatish Balay .  J   - Jacobian matrix
620a7e14dcfSSatish Balay -  ctx - [optional] user-defined Jacobian context
621a7e14dcfSSatish Balay 
622a7e14dcfSSatish Balay    Level: intermediate
623f4c1ad5cSStefano Zampini 
62465ba42b6SBarry Smith .seealso: `Tao`, `TaoComputeJacobianDesign()`, `TaoSetJacobianStateRoutine()`, `TaoSetStateDesignIS()`
625a7e14dcfSSatish Balay @*/
626*d71ae5a4SJacob Faibussowitsch PetscErrorCode TaoSetJacobianDesignRoutine(Tao tao, Mat J, PetscErrorCode (*func)(Tao, Vec, Mat, void *), void *ctx)
627*d71ae5a4SJacob Faibussowitsch {
628a7e14dcfSSatish Balay   PetscFunctionBegin;
629441846f8SBarry Smith   PetscValidHeaderSpecific(tao, TAO_CLASSID, 1);
630a7e14dcfSSatish Balay   if (J) {
631a7e14dcfSSatish Balay     PetscValidHeaderSpecific(J, MAT_CLASSID, 2);
632a7e14dcfSSatish Balay     PetscCheckSameComm(tao, 1, J, 2);
633a7e14dcfSSatish Balay   }
634ad540459SPierre Jolivet   if (ctx) tao->user_jac_designP = ctx;
635ad540459SPierre Jolivet   if (func) tao->ops->computejacobiandesign = func;
636a7e14dcfSSatish Balay   if (J) {
6379566063dSJacob Faibussowitsch     PetscCall(PetscObjectReference((PetscObject)J));
6389566063dSJacob Faibussowitsch     PetscCall(MatDestroy(&tao->jacobian_design));
639a7e14dcfSSatish Balay     tao->jacobian_design = J;
640a7e14dcfSSatish Balay   }
641a7e14dcfSSatish Balay   PetscFunctionReturn(0);
642a7e14dcfSSatish Balay }
643a7e14dcfSSatish Balay 
644a7e14dcfSSatish Balay /*@
645441846f8SBarry Smith    TaoSetStateDesignIS - Indicate to the Tao which variables in the
646a7e14dcfSSatish Balay    solution vector are state variables and which are design.  Only applies to
64765ba42b6SBarry Smith    PDE-constrained optimization.
648a7e14dcfSSatish Balay 
649441846f8SBarry Smith    Logically Collective on Tao
650a7e14dcfSSatish Balay 
651a7e14dcfSSatish Balay    Input Parameters:
652441846f8SBarry Smith +  tao  - The Tao context
653a7e14dcfSSatish Balay .  s_is - the index set corresponding to the state variables
654a7e14dcfSSatish Balay -  d_is - the index set corresponding to the design variables
655a7e14dcfSSatish Balay 
656a7e14dcfSSatish Balay    Level: intermediate
657a7e14dcfSSatish Balay 
65865ba42b6SBarry Smith .seealso: `Tao`, `TaoSetJacobianStateRoutine()`, `TaoSetJacobianDesignRoutine()`
659a7e14dcfSSatish Balay @*/
660*d71ae5a4SJacob Faibussowitsch PetscErrorCode TaoSetStateDesignIS(Tao tao, IS s_is, IS d_is)
661*d71ae5a4SJacob Faibussowitsch {
66245cf516eSBarry Smith   PetscFunctionBegin;
6639566063dSJacob Faibussowitsch   PetscCall(PetscObjectReference((PetscObject)s_is));
6649566063dSJacob Faibussowitsch   PetscCall(ISDestroy(&tao->state_is));
665a7e14dcfSSatish Balay   tao->state_is = s_is;
6669566063dSJacob Faibussowitsch   PetscCall(PetscObjectReference((PetscObject)(d_is)));
6679566063dSJacob Faibussowitsch   PetscCall(ISDestroy(&tao->design_is));
668a7e14dcfSSatish Balay   tao->design_is = d_is;
669a7e14dcfSSatish Balay   PetscFunctionReturn(0);
670a7e14dcfSSatish Balay }
671a7e14dcfSSatish Balay 
672a7e14dcfSSatish Balay /*@C
673a7e14dcfSSatish Balay    TaoComputeJacobianEquality - Computes the Jacobian matrix that has been
67465ba42b6SBarry Smith    set with `TaoSetJacobianEqualityRoutine()`.
675a7e14dcfSSatish Balay 
67665ba42b6SBarry Smith    Collective on tao
677a7e14dcfSSatish Balay 
678a7e14dcfSSatish Balay    Input Parameters:
679f4c1ad5cSStefano Zampini +  tao - the Tao solver context
680f4c1ad5cSStefano Zampini -  X   - input vector
681a7e14dcfSSatish Balay 
682a7e14dcfSSatish Balay    Output Parameters:
683f4c1ad5cSStefano Zampini +  J    - Jacobian matrix
684f4c1ad5cSStefano Zampini -  Jpre - Preconditioning matrix
685a7e14dcfSSatish Balay 
686a7e14dcfSSatish Balay    Notes:
687a7e14dcfSSatish Balay    Most users should not need to explicitly call this routine, as it
68865ba42b6SBarry Smith    is used internally within the optimization algorithms.
689a7e14dcfSSatish Balay 
690a7e14dcfSSatish Balay    Level: developer
691a7e14dcfSSatish Balay 
692db781477SPatrick Sanan .seealso: `TaoComputeObjective()`, `TaoComputeObjectiveAndGradient()`, `TaoSetJacobianStateRoutine()`, `TaoComputeJacobianDesign()`, `TaoSetStateDesignIS()`
693a7e14dcfSSatish Balay @*/
694*d71ae5a4SJacob Faibussowitsch PetscErrorCode TaoComputeJacobianEquality(Tao tao, Vec X, Mat J, Mat Jpre)
695*d71ae5a4SJacob Faibussowitsch {
696a7e14dcfSSatish Balay   PetscFunctionBegin;
697441846f8SBarry Smith   PetscValidHeaderSpecific(tao, TAO_CLASSID, 1);
698a7e14dcfSSatish Balay   PetscValidHeaderSpecific(X, VEC_CLASSID, 2);
699a7e14dcfSSatish Balay   PetscCheckSameComm(tao, 1, X, 2);
700a7e14dcfSSatish Balay   ++tao->njac_equality;
7019566063dSJacob Faibussowitsch   PetscCall(VecLockReadPush(X));
7029566063dSJacob Faibussowitsch   PetscCall(PetscLogEventBegin(TAO_JacobianEval, tao, X, J, Jpre));
703792fecdfSBarry Smith   PetscCallBack("Tao callback Jacobian(equality)", (*tao->ops->computejacobianequality)(tao, X, J, Jpre, tao->user_jac_equalityP));
7049566063dSJacob Faibussowitsch   PetscCall(PetscLogEventEnd(TAO_JacobianEval, tao, X, J, Jpre));
7059566063dSJacob Faibussowitsch   PetscCall(VecLockReadPop(X));
706a7e14dcfSSatish Balay   PetscFunctionReturn(0);
707a7e14dcfSSatish Balay }
708a7e14dcfSSatish Balay 
709a7e14dcfSSatish Balay /*@C
710a7e14dcfSSatish Balay    TaoComputeJacobianInequality - Computes the Jacobian matrix that has been
71165ba42b6SBarry Smith    set with `TaoSetJacobianInequalityRoutine()`.
712a7e14dcfSSatish Balay 
71365ba42b6SBarry Smith    Collective on tao
714a7e14dcfSSatish Balay 
715a7e14dcfSSatish Balay    Input Parameters:
716f4c1ad5cSStefano Zampini +  tao - the Tao solver context
717f4c1ad5cSStefano Zampini -  X   - input vector
718a7e14dcfSSatish Balay 
719a7e14dcfSSatish Balay    Output Parameters:
720f4c1ad5cSStefano Zampini +  J    - Jacobian matrix
721f4c1ad5cSStefano Zampini -  Jpre - Preconditioning matrix
722a7e14dcfSSatish Balay 
723a7e14dcfSSatish Balay    Notes:
724a7e14dcfSSatish Balay    Most users should not need to explicitly call this routine, as it
725a7e14dcfSSatish Balay    is used internally within the minimization solvers.
726a7e14dcfSSatish Balay 
727a7e14dcfSSatish Balay    Level: developer
728a7e14dcfSSatish Balay 
72965ba42b6SBarry Smith .seealso: `Tao`, `TaoComputeObjective()`, `TaoComputeObjectiveAndGradient()`, `TaoSetJacobianStateRoutine()`, `TaoComputeJacobianDesign()`, `TaoSetStateDesignIS()`
730a7e14dcfSSatish Balay @*/
731*d71ae5a4SJacob Faibussowitsch PetscErrorCode TaoComputeJacobianInequality(Tao tao, Vec X, Mat J, Mat Jpre)
732*d71ae5a4SJacob Faibussowitsch {
733a7e14dcfSSatish Balay   PetscFunctionBegin;
734441846f8SBarry Smith   PetscValidHeaderSpecific(tao, TAO_CLASSID, 1);
735a7e14dcfSSatish Balay   PetscValidHeaderSpecific(X, VEC_CLASSID, 2);
736a7e14dcfSSatish Balay   PetscCheckSameComm(tao, 1, X, 2);
737a7e14dcfSSatish Balay   ++tao->njac_inequality;
7389566063dSJacob Faibussowitsch   PetscCall(VecLockReadPush(X));
7399566063dSJacob Faibussowitsch   PetscCall(PetscLogEventBegin(TAO_JacobianEval, tao, X, J, Jpre));
740792fecdfSBarry Smith   PetscCallBack("Tao callback Jacobian (inequality)", (*tao->ops->computejacobianinequality)(tao, X, J, Jpre, tao->user_jac_inequalityP));
7419566063dSJacob Faibussowitsch   PetscCall(PetscLogEventEnd(TAO_JacobianEval, tao, X, J, Jpre));
7429566063dSJacob Faibussowitsch   PetscCall(VecLockReadPop(X));
743a7e14dcfSSatish Balay   PetscFunctionReturn(0);
744a7e14dcfSSatish Balay }
745a7e14dcfSSatish Balay 
746a7e14dcfSSatish Balay /*@C
747a7e14dcfSSatish Balay    TaoSetJacobianEqualityRoutine - Sets the function to compute the Jacobian
748a7e14dcfSSatish Balay    (and its inverse) of the constraint function with respect to the equality variables.
74965ba42b6SBarry Smith    Used only for PDE-constrained optimization.
750a7e14dcfSSatish Balay 
75165ba42b6SBarry Smith    Logically collective on tao
752a7e14dcfSSatish Balay 
753a7e14dcfSSatish Balay    Input Parameters:
754441846f8SBarry Smith +  tao  - the Tao context
755a7e14dcfSSatish Balay .  J    - Matrix used for the jacobian
756a7e14dcfSSatish Balay .  Jpre - Matrix that will be used operated on by PETSc preconditioner, can be same as J.
757f4c1ad5cSStefano Zampini .  func - Jacobian evaluation routine
758a7e14dcfSSatish Balay -  ctx  - [optional] user-defined context for private data for the
7596c23d075SBarry Smith           Jacobian evaluation routine (may be NULL)
760a7e14dcfSSatish Balay 
761f4c1ad5cSStefano Zampini    Calling sequence of func:
762f4c1ad5cSStefano Zampini $    func(Tao tao,Vec x,Mat J,Mat Jpre,void *ctx);
763a7e14dcfSSatish Balay 
764441846f8SBarry Smith +  tao  - the Tao  context
765a7e14dcfSSatish Balay .  x    - input vector
766a7e14dcfSSatish Balay .  J    - Jacobian matrix
767a7e14dcfSSatish Balay .  Jpre - preconditioner matrix, usually the same as J
768a7e14dcfSSatish Balay -  ctx  - [optional] user-defined Jacobian context
769a7e14dcfSSatish Balay 
770a7e14dcfSSatish Balay    Level: intermediate
771f4c1ad5cSStefano Zampini 
77265ba42b6SBarry Smith .seealso: `Tao`, `TaoComputeJacobianEquality()`, `TaoSetJacobianDesignRoutine()`, `TaoSetEqualityDesignIS()`
773a7e14dcfSSatish Balay @*/
774*d71ae5a4SJacob Faibussowitsch PetscErrorCode TaoSetJacobianEqualityRoutine(Tao tao, Mat J, Mat Jpre, PetscErrorCode (*func)(Tao, Vec, Mat, Mat, void *), void *ctx)
775*d71ae5a4SJacob Faibussowitsch {
776a7e14dcfSSatish Balay   PetscFunctionBegin;
777441846f8SBarry Smith   PetscValidHeaderSpecific(tao, TAO_CLASSID, 1);
778a7e14dcfSSatish Balay   if (J) {
779a7e14dcfSSatish Balay     PetscValidHeaderSpecific(J, MAT_CLASSID, 2);
780a7e14dcfSSatish Balay     PetscCheckSameComm(tao, 1, J, 2);
781a7e14dcfSSatish Balay   }
782a7e14dcfSSatish Balay   if (Jpre) {
783a7e14dcfSSatish Balay     PetscValidHeaderSpecific(Jpre, MAT_CLASSID, 3);
784a7e14dcfSSatish Balay     PetscCheckSameComm(tao, 1, Jpre, 3);
785a7e14dcfSSatish Balay   }
786ad540459SPierre Jolivet   if (ctx) tao->user_jac_equalityP = ctx;
787ad540459SPierre Jolivet   if (func) tao->ops->computejacobianequality = func;
788a7e14dcfSSatish Balay   if (J) {
7899566063dSJacob Faibussowitsch     PetscCall(PetscObjectReference((PetscObject)J));
7909566063dSJacob Faibussowitsch     PetscCall(MatDestroy(&tao->jacobian_equality));
791a7e14dcfSSatish Balay     tao->jacobian_equality = J;
792a7e14dcfSSatish Balay   }
793a7e14dcfSSatish Balay   if (Jpre) {
7949566063dSJacob Faibussowitsch     PetscCall(PetscObjectReference((PetscObject)Jpre));
7959566063dSJacob Faibussowitsch     PetscCall(MatDestroy(&tao->jacobian_equality_pre));
796a7e14dcfSSatish Balay     tao->jacobian_equality_pre = Jpre;
797a7e14dcfSSatish Balay   }
798a7e14dcfSSatish Balay   PetscFunctionReturn(0);
799a7e14dcfSSatish Balay }
800a7e14dcfSSatish Balay 
801a7e14dcfSSatish Balay /*@C
802a7e14dcfSSatish Balay    TaoSetJacobianInequalityRoutine - Sets the function to compute the Jacobian
803a7e14dcfSSatish Balay    (and its inverse) of the constraint function with respect to the inequality variables.
80465ba42b6SBarry Smith    Used only for PDE-constrained optimization.
805a7e14dcfSSatish Balay 
80665ba42b6SBarry Smith    Logically collective on tao
807a7e14dcfSSatish Balay 
808a7e14dcfSSatish Balay    Input Parameters:
809441846f8SBarry Smith +  tao  - the Tao context
810a7e14dcfSSatish Balay .  J    - Matrix used for the jacobian
811a7e14dcfSSatish Balay .  Jpre - Matrix that will be used operated on by PETSc preconditioner, can be same as J.
812f4c1ad5cSStefano Zampini .  func - Jacobian evaluation routine
813a7e14dcfSSatish Balay -  ctx  - [optional] user-defined context for private data for the
8146c23d075SBarry Smith           Jacobian evaluation routine (may be NULL)
815a7e14dcfSSatish Balay 
816f4c1ad5cSStefano Zampini    Calling sequence of func:
817f4c1ad5cSStefano Zampini $    func(Tao tao,Vec x,Mat J,Mat Jpre,void *ctx);
818a7e14dcfSSatish Balay 
819441846f8SBarry Smith +  tao  - the Tao  context
820a7e14dcfSSatish Balay .  x    - input vector
821a7e14dcfSSatish Balay .  J    - Jacobian matrix
822a7e14dcfSSatish Balay .  Jpre - preconditioner matrix, usually the same as J
823a7e14dcfSSatish Balay -  ctx  - [optional] user-defined Jacobian context
824a7e14dcfSSatish Balay 
825a7e14dcfSSatish Balay    Level: intermediate
826f4c1ad5cSStefano Zampini 
82765ba42b6SBarry Smith .seealso: `Tao`, `TaoComputeJacobianInequality()`, `TaoSetJacobianDesignRoutine()`, `TaoSetInequalityDesignIS()`
828a7e14dcfSSatish Balay @*/
829*d71ae5a4SJacob Faibussowitsch PetscErrorCode TaoSetJacobianInequalityRoutine(Tao tao, Mat J, Mat Jpre, PetscErrorCode (*func)(Tao, Vec, Mat, Mat, void *), void *ctx)
830*d71ae5a4SJacob Faibussowitsch {
831a7e14dcfSSatish Balay   PetscFunctionBegin;
832441846f8SBarry Smith   PetscValidHeaderSpecific(tao, TAO_CLASSID, 1);
833a7e14dcfSSatish Balay   if (J) {
834a7e14dcfSSatish Balay     PetscValidHeaderSpecific(J, MAT_CLASSID, 2);
835a7e14dcfSSatish Balay     PetscCheckSameComm(tao, 1, J, 2);
836a7e14dcfSSatish Balay   }
837a7e14dcfSSatish Balay   if (Jpre) {
838a7e14dcfSSatish Balay     PetscValidHeaderSpecific(Jpre, MAT_CLASSID, 3);
839a7e14dcfSSatish Balay     PetscCheckSameComm(tao, 1, Jpre, 3);
840a7e14dcfSSatish Balay   }
841ad540459SPierre Jolivet   if (ctx) tao->user_jac_inequalityP = ctx;
842ad540459SPierre Jolivet   if (func) tao->ops->computejacobianinequality = func;
843a7e14dcfSSatish Balay   if (J) {
8449566063dSJacob Faibussowitsch     PetscCall(PetscObjectReference((PetscObject)J));
8459566063dSJacob Faibussowitsch     PetscCall(MatDestroy(&tao->jacobian_inequality));
846a7e14dcfSSatish Balay     tao->jacobian_inequality = J;
847a7e14dcfSSatish Balay   }
848a7e14dcfSSatish Balay   if (Jpre) {
8499566063dSJacob Faibussowitsch     PetscCall(PetscObjectReference((PetscObject)Jpre));
8509566063dSJacob Faibussowitsch     PetscCall(MatDestroy(&tao->jacobian_inequality_pre));
851a7e14dcfSSatish Balay     tao->jacobian_inequality_pre = Jpre;
852a7e14dcfSSatish Balay   }
853a7e14dcfSSatish Balay   PetscFunctionReturn(0);
854a7e14dcfSSatish Balay }
855