xref: /petsc/src/tao/interface/taosolver_hj.c (revision 1cc06b555e92f8ec64db10330b8bbd830e5bc876)
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 
620f4b53cSBarry Smith    Logically Collective
7a7e14dcfSSatish Balay 
8a7e14dcfSSatish Balay    Input Parameters:
947450a7bSBarry Smith +  tao  - the `Tao` context
10a7e14dcfSSatish Balay .  H    - Matrix used for the hessian
1147450a7bSBarry Smith .  Hpre - Matrix that will be used to construct the preconditioner, can be same as `H`
12f4c1ad5cSStefano Zampini .  func - Hessian evaluation routine
13a7e14dcfSSatish Balay -  ctx  - [optional] user-defined context for private data for the
1447450a7bSBarry Smith          Hessian evaluation routine (may be `NULL`)
15a7e14dcfSSatish Balay 
1620f4b53cSBarry Smith    Calling sequence of `func`:
1720f4b53cSBarry Smith $  PetscErrorCode func(Tao tao, Vec x, Mat H, Mat Hpre, void *ctx);
18441846f8SBarry Smith +  tao  - the Tao  context
19a7e14dcfSSatish Balay .  x    - input vector
20a7e14dcfSSatish Balay .  H    - Hessian matrix
2147450a7bSBarry Smith .  Hpre - matrix used to construct the preconditioner, usually the same as `H`
22a7e14dcfSSatish Balay -  ctx  - [optional] user-defined Hessian context
23a7e14dcfSSatish Balay 
24a7e14dcfSSatish Balay    Level: beginner
25a82e8c82SStefano Zampini 
26*1cc06b55SBarry Smith .seealso: [](ch_tao), `Tao`, `TaoTypes`, `TaoSetObjective()`, `TaoSetGradient()`, `TaoSetObjectiveAndGradient()`, `TaoGetHessian()`
27a7e14dcfSSatish Balay @*/
28d71ae5a4SJacob Faibussowitsch PetscErrorCode TaoSetHessian(Tao tao, Mat H, Mat Hpre, PetscErrorCode (*func)(Tao, Vec, Mat, Mat, void *), void *ctx)
29d71ae5a4SJacob Faibussowitsch {
30a7e14dcfSSatish Balay   PetscFunctionBegin;
31441846f8SBarry Smith   PetscValidHeaderSpecific(tao, TAO_CLASSID, 1);
32a7e14dcfSSatish Balay   if (H) {
33a7e14dcfSSatish Balay     PetscValidHeaderSpecific(H, MAT_CLASSID, 2);
34a7e14dcfSSatish Balay     PetscCheckSameComm(tao, 1, H, 2);
35a7e14dcfSSatish Balay   }
36a7e14dcfSSatish Balay   if (Hpre) {
37a7e14dcfSSatish Balay     PetscValidHeaderSpecific(Hpre, MAT_CLASSID, 3);
38a7e14dcfSSatish Balay     PetscCheckSameComm(tao, 1, Hpre, 3);
39a7e14dcfSSatish Balay   }
40a82e8c82SStefano Zampini   if (ctx) tao->user_hessP = ctx;
41a82e8c82SStefano Zampini   if (func) tao->ops->computehessian = func;
42a7e14dcfSSatish Balay   if (H) {
439566063dSJacob Faibussowitsch     PetscCall(PetscObjectReference((PetscObject)H));
449566063dSJacob Faibussowitsch     PetscCall(MatDestroy(&tao->hessian));
45a7e14dcfSSatish Balay     tao->hessian = H;
46a7e14dcfSSatish Balay   }
47a7e14dcfSSatish Balay   if (Hpre) {
489566063dSJacob Faibussowitsch     PetscCall(PetscObjectReference((PetscObject)Hpre));
499566063dSJacob Faibussowitsch     PetscCall(MatDestroy(&tao->hessian_pre));
50a7e14dcfSSatish Balay     tao->hessian_pre = Hpre;
51a7e14dcfSSatish Balay   }
523ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
53a7e14dcfSSatish Balay }
54a7e14dcfSSatish Balay 
55a82e8c82SStefano Zampini /*@C
56a82e8c82SStefano Zampini    TaoGetHessian - Gets the function to compute the Hessian as well as the location to store the matrix.
57a82e8c82SStefano Zampini 
5820f4b53cSBarry Smith    Not Collective
59a82e8c82SStefano Zampini 
60a82e8c82SStefano Zampini    Input Parameter:
6147450a7bSBarry Smith .  tao  - the `Tao` context
62a82e8c82SStefano Zampini 
63a82e8c82SStefano Zampini    OutputParameters:
64a82e8c82SStefano Zampini +  H    - Matrix used for the hessian
6547450a7bSBarry Smith .  Hpre - Matrix that will be used to construct the preconditioner, can be the same as `H`
66a82e8c82SStefano Zampini .  func - Hessian evaluation routine
67a82e8c82SStefano Zampini -  ctx  - user-defined context for private data for the Hessian evaluation routine
68a82e8c82SStefano Zampini 
6920f4b53cSBarry Smith    Calling sequence of `func`:
7020f4b53cSBarry Smith $  PetscErrorCode func(Tao tao, Vec x, Mat H, Mat Hpre, void *ctx);
71a82e8c82SStefano Zampini +  tao  - the Tao  context
72a82e8c82SStefano Zampini .  x    - input vector
73a82e8c82SStefano Zampini .  H    - Hessian matrix
7447450a7bSBarry Smith .  Hpre - matrix used to construct the preconditioner, usually the same as `H`
75a82e8c82SStefano Zampini -  ctx  - [optional] user-defined Hessian context
76a82e8c82SStefano Zampini 
77a82e8c82SStefano Zampini    Level: beginner
78a82e8c82SStefano Zampini 
79*1cc06b55SBarry Smith .seealso: [](ch_tao), `Tao`, TaoType`, `TaoGetObjective()`, `TaoGetGradient()`, `TaoGetObjectiveAndGradient()`, `TaoSetHessian()`
80a82e8c82SStefano Zampini @*/
81d71ae5a4SJacob Faibussowitsch PetscErrorCode TaoGetHessian(Tao tao, Mat *H, Mat *Hpre, PetscErrorCode (**func)(Tao, Vec, Mat, Mat, void *), void **ctx)
82d71ae5a4SJacob Faibussowitsch {
83a82e8c82SStefano Zampini   PetscFunctionBegin;
84a82e8c82SStefano Zampini   PetscValidHeaderSpecific(tao, TAO_CLASSID, 1);
85a82e8c82SStefano Zampini   if (H) *H = tao->hessian;
86a82e8c82SStefano Zampini   if (Hpre) *Hpre = tao->hessian_pre;
87a82e8c82SStefano Zampini   if (ctx) *ctx = tao->user_hessP;
88a82e8c82SStefano Zampini   if (func) *func = tao->ops->computehessian;
893ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
90a82e8c82SStefano Zampini }
91a82e8c82SStefano Zampini 
92d71ae5a4SJacob Faibussowitsch PetscErrorCode TaoTestHessian(Tao tao)
93d71ae5a4SJacob Faibussowitsch {
9409baa881SHong Zhang   Mat               A, B, C, D, hessian;
9509baa881SHong Zhang   Vec               x = tao->solution;
9609baa881SHong Zhang   PetscReal         nrm, gnorm;
9709baa881SHong Zhang   PetscReal         threshold = 1.e-5;
9809baa881SHong Zhang   PetscInt          m, n, M, N;
9909baa881SHong Zhang   PetscBool         complete_print = PETSC_FALSE, test = PETSC_FALSE, flg;
100f49d1c87SHong Zhang   PetscViewer       viewer, mviewer;
10109baa881SHong Zhang   MPI_Comm          comm;
10209baa881SHong Zhang   PetscInt          tabs;
10309baa881SHong Zhang   static PetscBool  directionsprinted = PETSC_FALSE;
104f49d1c87SHong Zhang   PetscViewerFormat format;
10509baa881SHong Zhang 
10609baa881SHong Zhang   PetscFunctionBegin;
107d0609cedSBarry Smith   PetscObjectOptionsBegin((PetscObject)tao);
1089566063dSJacob Faibussowitsch   PetscCall(PetscOptionsName("-tao_test_hessian", "Compare hand-coded and finite difference Hessians", "None", &test));
1099566063dSJacob Faibussowitsch   PetscCall(PetscOptionsReal("-tao_test_hessian", "Threshold for element difference between hand-coded and finite difference being meaningful", "None", threshold, &threshold, NULL));
1109566063dSJacob Faibussowitsch   PetscCall(PetscOptionsViewer("-tao_test_hessian_view", "View difference between hand-coded and finite difference Hessians element entries", "None", &mviewer, &format, &complete_print));
111d0609cedSBarry Smith   PetscOptionsEnd();
1123ba16761SJacob Faibussowitsch   if (!test) PetscFunctionReturn(PETSC_SUCCESS);
11309baa881SHong Zhang 
1149566063dSJacob Faibussowitsch   PetscCall(PetscObjectGetComm((PetscObject)tao, &comm));
1159566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIGetStdout(comm, &viewer));
1169566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIGetTab(viewer, &tabs));
1179566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIISetTab(viewer, ((PetscObject)tao)->tablevel));
1189566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPrintf(viewer, "  ---------- Testing Hessian -------------\n"));
11909baa881SHong Zhang   if (!complete_print && !directionsprinted) {
1209566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer, "  Run with -tao_test_hessian_view and optionally -tao_test_hessian <threshold> to show difference\n"));
1219566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer, "    of hand-coded and finite difference Hessian entries greater than <threshold>.\n"));
12209baa881SHong Zhang   }
12309baa881SHong Zhang   if (!directionsprinted) {
1249566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer, "  Testing hand-coded Hessian, if (for double precision runs) ||J - Jfd||_F/||J||_F is\n"));
1259566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer, "    O(1.e-8), the hand-coded Hessian is probably correct.\n"));
12609baa881SHong Zhang     directionsprinted = PETSC_TRUE;
12709baa881SHong Zhang   }
1281baa6e33SBarry Smith   if (complete_print) PetscCall(PetscViewerPushFormat(mviewer, format));
12909baa881SHong Zhang 
1309566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)tao->hessian, MATMFFD, &flg));
13109baa881SHong Zhang   if (!flg) hessian = tao->hessian;
13209baa881SHong Zhang   else hessian = tao->hessian_pre;
13309baa881SHong Zhang 
13409baa881SHong Zhang   while (hessian) {
1359566063dSJacob Faibussowitsch     PetscCall(PetscObjectBaseTypeCompareAny((PetscObject)hessian, &flg, MATSEQAIJ, MATMPIAIJ, MATSEQDENSE, MATMPIDENSE, MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPIBAIJ, ""));
13609baa881SHong Zhang     if (flg) {
13709baa881SHong Zhang       A = hessian;
1389566063dSJacob Faibussowitsch       PetscCall(PetscObjectReference((PetscObject)A));
13909baa881SHong Zhang     } else {
1409566063dSJacob Faibussowitsch       PetscCall(MatComputeOperator(hessian, MATAIJ, &A));
14109baa881SHong Zhang     }
14209baa881SHong Zhang 
1439566063dSJacob Faibussowitsch     PetscCall(MatCreate(PetscObjectComm((PetscObject)A), &B));
1449566063dSJacob Faibussowitsch     PetscCall(MatGetSize(A, &M, &N));
1459566063dSJacob Faibussowitsch     PetscCall(MatGetLocalSize(A, &m, &n));
1469566063dSJacob Faibussowitsch     PetscCall(MatSetSizes(B, m, n, M, N));
1479566063dSJacob Faibussowitsch     PetscCall(MatSetType(B, ((PetscObject)A)->type_name));
1489566063dSJacob Faibussowitsch     PetscCall(MatSetUp(B));
1499566063dSJacob Faibussowitsch     PetscCall(MatSetOption(B, MAT_NEW_NONZERO_ALLOCATION_ERR, PETSC_FALSE));
15009baa881SHong Zhang 
1519566063dSJacob Faibussowitsch     PetscCall(TaoDefaultComputeHessian(tao, x, B, B, NULL));
15209baa881SHong Zhang 
1539566063dSJacob Faibussowitsch     PetscCall(MatDuplicate(B, MAT_COPY_VALUES, &D));
1549566063dSJacob Faibussowitsch     PetscCall(MatAYPX(D, -1.0, A, DIFFERENT_NONZERO_PATTERN));
1559566063dSJacob Faibussowitsch     PetscCall(MatNorm(D, NORM_FROBENIUS, &nrm));
1569566063dSJacob Faibussowitsch     PetscCall(MatNorm(A, NORM_FROBENIUS, &gnorm));
1579566063dSJacob Faibussowitsch     PetscCall(MatDestroy(&D));
15809baa881SHong Zhang     if (!gnorm) gnorm = 1; /* just in case */
1599566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer, "  ||H - Hfd||_F/||H||_F = %g, ||H - Hfd||_F = %g\n", (double)(nrm / gnorm), (double)nrm));
16009baa881SHong Zhang 
16109baa881SHong Zhang     if (complete_print) {
1629566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer, "  Hand-coded Hessian ----------\n"));
1639566063dSJacob Faibussowitsch       PetscCall(MatView(A, mviewer));
1649566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer, "  Finite difference Hessian ----------\n"));
1659566063dSJacob Faibussowitsch       PetscCall(MatView(B, mviewer));
16609baa881SHong Zhang     }
16709baa881SHong Zhang 
16809baa881SHong Zhang     if (complete_print) {
16909baa881SHong Zhang       PetscInt           Istart, Iend, *ccols, bncols, cncols, j, row;
17009baa881SHong Zhang       PetscScalar       *cvals;
17109baa881SHong Zhang       const PetscInt    *bcols;
17209baa881SHong Zhang       const PetscScalar *bvals;
17309baa881SHong Zhang 
1749566063dSJacob Faibussowitsch       PetscCall(MatAYPX(B, -1.0, A, DIFFERENT_NONZERO_PATTERN));
1759566063dSJacob Faibussowitsch       PetscCall(MatCreate(PetscObjectComm((PetscObject)A), &C));
1769566063dSJacob Faibussowitsch       PetscCall(MatSetSizes(C, m, n, M, N));
1779566063dSJacob Faibussowitsch       PetscCall(MatSetType(C, ((PetscObject)A)->type_name));
1789566063dSJacob Faibussowitsch       PetscCall(MatSetUp(C));
1799566063dSJacob Faibussowitsch       PetscCall(MatSetOption(C, MAT_NEW_NONZERO_ALLOCATION_ERR, PETSC_FALSE));
1809566063dSJacob Faibussowitsch       PetscCall(MatGetOwnershipRange(B, &Istart, &Iend));
18109baa881SHong Zhang 
18209baa881SHong Zhang       for (row = Istart; row < Iend; row++) {
1839566063dSJacob Faibussowitsch         PetscCall(MatGetRow(B, row, &bncols, &bcols, &bvals));
1849566063dSJacob Faibussowitsch         PetscCall(PetscMalloc2(bncols, &ccols, bncols, &cvals));
18509baa881SHong Zhang         for (j = 0, cncols = 0; j < bncols; j++) {
18609baa881SHong Zhang           if (PetscAbsScalar(bvals[j]) > threshold) {
18709baa881SHong Zhang             ccols[cncols] = bcols[j];
18809baa881SHong Zhang             cvals[cncols] = bvals[j];
18909baa881SHong Zhang             cncols += 1;
19009baa881SHong Zhang           }
19109baa881SHong Zhang         }
19248a46eb9SPierre Jolivet         if (cncols) PetscCall(MatSetValues(C, 1, &row, cncols, ccols, cvals, INSERT_VALUES));
1939566063dSJacob Faibussowitsch         PetscCall(MatRestoreRow(B, row, &bncols, &bcols, &bvals));
1949566063dSJacob Faibussowitsch         PetscCall(PetscFree2(ccols, cvals));
19509baa881SHong Zhang       }
1969566063dSJacob Faibussowitsch       PetscCall(MatAssemblyBegin(C, MAT_FINAL_ASSEMBLY));
1979566063dSJacob Faibussowitsch       PetscCall(MatAssemblyEnd(C, MAT_FINAL_ASSEMBLY));
1989566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer, "  Finite-difference minus hand-coded Hessian with tolerance %g ----------\n", (double)threshold));
1999566063dSJacob Faibussowitsch       PetscCall(MatView(C, mviewer));
2009566063dSJacob Faibussowitsch       PetscCall(MatDestroy(&C));
20109baa881SHong Zhang     }
2029566063dSJacob Faibussowitsch     PetscCall(MatDestroy(&A));
2039566063dSJacob Faibussowitsch     PetscCall(MatDestroy(&B));
20409baa881SHong Zhang 
20509baa881SHong Zhang     if (hessian != tao->hessian_pre) {
20609baa881SHong Zhang       hessian = tao->hessian_pre;
2079566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer, "  ---------- Testing Hessian for preconditioner -------------\n"));
20809baa881SHong Zhang     } else hessian = NULL;
20909baa881SHong Zhang   }
210f49d1c87SHong Zhang   if (complete_print) {
2119566063dSJacob Faibussowitsch     PetscCall(PetscViewerPopFormat(mviewer));
2129566063dSJacob Faibussowitsch     PetscCall(PetscViewerDestroy(&mviewer));
213f49d1c87SHong Zhang   }
2149566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIISetTab(viewer, tabs));
2153ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
21609baa881SHong Zhang }
21709baa881SHong Zhang 
218a7e14dcfSSatish Balay /*@C
219a7e14dcfSSatish Balay    TaoComputeHessian - Computes the Hessian matrix that has been
22065ba42b6SBarry Smith    set with `TaoSetHessian()`.
221a7e14dcfSSatish Balay 
222c3339decSBarry Smith    Collective
223a7e14dcfSSatish Balay 
224a7e14dcfSSatish Balay    Input Parameters:
225f4c1ad5cSStefano Zampini +  tao - the Tao solver context
226f4c1ad5cSStefano Zampini -  X   - input vector
227a7e14dcfSSatish Balay 
228a7e14dcfSSatish Balay    Output Parameters:
229a7e14dcfSSatish Balay +  H    - Hessian matrix
230aa6c7ce3SBarry Smith -  Hpre - Preconditioning matrix
231a7e14dcfSSatish Balay 
23209baa881SHong Zhang    Options Database Keys:
23309baa881SHong Zhang +     -tao_test_hessian - compare the user provided Hessian with one compute via finite differences to check for errors
23409baa881SHong 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
235dfe02fe6SHong 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
23609baa881SHong Zhang 
23747450a7bSBarry Smith    Level: developer
23847450a7bSBarry Smith 
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 
250*1cc06b55SBarry Smith .seealso: [](ch_tao), `Tao`, `TaoComputeObjective()`, `TaoComputeObjectiveAndGradient()`, `TaoSetHessian()`
251a7e14dcfSSatish Balay @*/
252d71ae5a4SJacob Faibussowitsch PetscErrorCode TaoComputeHessian(Tao tao, Vec X, Mat H, Mat Hpre)
253d71ae5a4SJacob Faibussowitsch {
254a7e14dcfSSatish Balay   PetscFunctionBegin;
255441846f8SBarry Smith   PetscValidHeaderSpecific(tao, TAO_CLASSID, 1);
256a7e14dcfSSatish Balay   PetscValidHeaderSpecific(X, VEC_CLASSID, 2);
257a7e14dcfSSatish Balay   PetscCheckSameComm(tao, 1, X, 2);
258794dad8cSStefano Zampini   PetscCheck(tao->ops->computehessian, PetscObjectComm((PetscObject)tao), PETSC_ERR_ARG_WRONGSTATE, "TaoSetHessian() not called");
259794dad8cSStefano Zampini 
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));
2683ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
269a7e14dcfSSatish Balay }
270a7e14dcfSSatish Balay 
271a7e14dcfSSatish Balay /*@C
272a7e14dcfSSatish Balay    TaoComputeJacobian - Computes the Jacobian matrix that has been
273a7e14dcfSSatish Balay    set with TaoSetJacobianRoutine().
274a7e14dcfSSatish Balay 
275c3339decSBarry Smith    Collective
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 
28547450a7bSBarry Smith    Level: developer
28647450a7bSBarry Smith 
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 
295*1cc06b55SBarry Smith .seealso: [](ch_tao), `TaoComputeObjective()`, `TaoComputeObjectiveAndGradient()`, `TaoSetJacobianRoutine()`
296a7e14dcfSSatish Balay @*/
297d71ae5a4SJacob Faibussowitsch PetscErrorCode TaoComputeJacobian(Tao tao, Vec X, Mat J, Mat Jpre)
298d71ae5a4SJacob 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));
3093ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
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 
316c3339decSBarry Smith    Collective
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 
32647450a7bSBarry Smith    Level: developer
32747450a7bSBarry Smith 
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 
336*1cc06b55SBarry Smith .seealso: [](ch_tao), `Tao`, `TaoComputeResidual()`, `TaoSetJacobianResidual()`
3374a48860cSAlp Dener @*/
338d71ae5a4SJacob Faibussowitsch PetscErrorCode TaoComputeResidualJacobian(Tao tao, Vec X, Mat J, Mat Jpre)
339d71ae5a4SJacob 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));
3503ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
3514a48860cSAlp Dener }
3524a48860cSAlp Dener 
3534a48860cSAlp Dener /*@C
354a7e14dcfSSatish Balay    TaoComputeJacobianState - Computes the Jacobian matrix that has been
35565ba42b6SBarry Smith    set with `TaoSetJacobianStateRoutine()`.
356a7e14dcfSSatish Balay 
357c3339decSBarry Smith    Collective
358a7e14dcfSSatish Balay 
359a7e14dcfSSatish Balay    Input Parameters:
36047450a7bSBarry Smith +  tao - the `Tao` solver context
361f4c1ad5cSStefano Zampini -  X   - input vector
362a7e14dcfSSatish Balay 
363a7e14dcfSSatish Balay    Output Parameters:
3646b867d5aSJose E. Roman +  J    - Jacobian matrix
36547450a7bSBarry Smith .  Jpre - matrix used to construct the preconditioner, often the same as `J`
36665ba42b6SBarry Smith -  Jinv - unknown
367a7e14dcfSSatish Balay 
368a7e14dcfSSatish Balay    Level: developer
369a7e14dcfSSatish Balay 
37047450a7bSBarry Smith    Note:
37147450a7bSBarry Smith    Most users should not need to explicitly call this routine, as it
37247450a7bSBarry Smith    is used internally within the optimization algorithms.
37347450a7bSBarry Smith 
374*1cc06b55SBarry Smith .seealso: [](ch_tao), `Tao`, `TaoComputeObjective()`, `TaoComputeObjectiveAndGradient()`, `TaoSetJacobianStateRoutine()`, `TaoComputeJacobianDesign()`, `TaoSetStateDesignIS()`
375a7e14dcfSSatish Balay @*/
376d71ae5a4SJacob Faibussowitsch PetscErrorCode TaoComputeJacobianState(Tao tao, Vec X, Mat J, Mat Jpre, Mat Jinv)
377d71ae5a4SJacob 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));
3883ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
389a7e14dcfSSatish Balay }
390a7e14dcfSSatish Balay 
391a7e14dcfSSatish Balay /*@C
392a7e14dcfSSatish Balay    TaoComputeJacobianDesign - Computes the Jacobian matrix that has been
39365ba42b6SBarry Smith    set with `TaoSetJacobianDesignRoutine()`.
394a7e14dcfSSatish Balay 
395c3339decSBarry Smith    Collective
396a7e14dcfSSatish Balay 
397a7e14dcfSSatish Balay    Input Parameters:
398f4c1ad5cSStefano Zampini +  tao - the Tao solver context
399f4c1ad5cSStefano Zampini -  X   - input vector
400a7e14dcfSSatish Balay 
4012fe279fdSBarry Smith    Output Parameter:
402f4c1ad5cSStefano Zampini .  J - Jacobian matrix
403a7e14dcfSSatish Balay 
40447450a7bSBarry Smith    Level: developer
40547450a7bSBarry Smith 
40647450a7bSBarry Smith    Note:
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 
410*1cc06b55SBarry Smith .seealso: [](ch_tao), `Tao`, `TaoComputeObjective()`, `TaoComputeObjectiveAndGradient()`, `TaoSetJacobianDesignRoutine()`, `TaoComputeJacobianDesign()`, `TaoSetStateDesignIS()`
411a7e14dcfSSatish Balay @*/
412d71ae5a4SJacob Faibussowitsch PetscErrorCode TaoComputeJacobianDesign(Tao tao, Vec X, Mat J)
413d71ae5a4SJacob 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));
4243ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
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 
43020f4b53cSBarry Smith    Logically Collective
431a7e14dcfSSatish Balay 
432a7e14dcfSSatish Balay    Input Parameters:
43347450a7bSBarry Smith +  tao  - the `Tao` context
43447450a7bSBarry Smith .  J    - Matrix used for the Jacobian
43547450a7bSBarry Smith .  Jpre - Matrix that will be used to construct the preconditioner, can be same as `J`
436f4c1ad5cSStefano Zampini .  func - Jacobian evaluation routine
437a7e14dcfSSatish Balay -  ctx  - [optional] user-defined context for private data for the
43847450a7bSBarry Smith           Jacobian evaluation routine (may be `NULL`)
439a7e14dcfSSatish Balay 
44020f4b53cSBarry Smith    Calling sequence of `func`:
44120f4b53cSBarry Smith $  PetscErrorCode func(Tao tao, Vec x, Mat J, Mat Jpre, void *ctx);
44247450a7bSBarry Smith +  tao  - the `Tao` context
443a7e14dcfSSatish Balay .  x    - input vector
444a7e14dcfSSatish Balay .  J    - Jacobian matrix
44547450a7bSBarry Smith .  Jpre - matrix used to construct the preconditioner, usually the same as `J`
446a7e14dcfSSatish Balay -  ctx  - [optional] user-defined Jacobian context
447a7e14dcfSSatish Balay 
448a7e14dcfSSatish Balay    Level: intermediate
44965ba42b6SBarry Smith 
450*1cc06b55SBarry Smith .seealso: [](ch_tao), `Tao`, `TaoSetGradient()`, `TaoSetObjective()`
451a7e14dcfSSatish Balay @*/
452d71ae5a4SJacob Faibussowitsch PetscErrorCode TaoSetJacobianRoutine(Tao tao, Mat J, Mat Jpre, PetscErrorCode (*func)(Tao, Vec, Mat, Mat, void *), void *ctx)
453d71ae5a4SJacob Faibussowitsch {
454a7e14dcfSSatish Balay   PetscFunctionBegin;
455441846f8SBarry Smith   PetscValidHeaderSpecific(tao, TAO_CLASSID, 1);
456a7e14dcfSSatish Balay   if (J) {
457a7e14dcfSSatish Balay     PetscValidHeaderSpecific(J, MAT_CLASSID, 2);
458a7e14dcfSSatish Balay     PetscCheckSameComm(tao, 1, J, 2);
459a7e14dcfSSatish Balay   }
460a7e14dcfSSatish Balay   if (Jpre) {
461a7e14dcfSSatish Balay     PetscValidHeaderSpecific(Jpre, MAT_CLASSID, 3);
462a7e14dcfSSatish Balay     PetscCheckSameComm(tao, 1, Jpre, 3);
463a7e14dcfSSatish Balay   }
464ad540459SPierre Jolivet   if (ctx) tao->user_jacP = ctx;
465ad540459SPierre Jolivet   if (func) tao->ops->computejacobian = func;
466a7e14dcfSSatish Balay   if (J) {
4679566063dSJacob Faibussowitsch     PetscCall(PetscObjectReference((PetscObject)J));
4689566063dSJacob Faibussowitsch     PetscCall(MatDestroy(&tao->jacobian));
469a7e14dcfSSatish Balay     tao->jacobian = J;
470a7e14dcfSSatish Balay   }
471a7e14dcfSSatish Balay   if (Jpre) {
4729566063dSJacob Faibussowitsch     PetscCall(PetscObjectReference((PetscObject)Jpre));
4739566063dSJacob Faibussowitsch     PetscCall(MatDestroy(&tao->jacobian_pre));
474a7e14dcfSSatish Balay     tao->jacobian_pre = Jpre;
475a7e14dcfSSatish Balay   }
4763ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
477a7e14dcfSSatish Balay }
478a7e14dcfSSatish Balay 
479a7e14dcfSSatish Balay /*@C
4804ffbe8acSAlp Dener    TaoSetJacobianResidualRoutine - Sets the function to compute the least-squares residual Jacobian as well as the
4814a48860cSAlp Dener    location to store the matrix.
4824a48860cSAlp Dener 
48320f4b53cSBarry Smith    Logically Collective
4844a48860cSAlp Dener 
4854a48860cSAlp Dener    Input Parameters:
48647450a7bSBarry Smith +  tao  - the `Tao` context
4874a48860cSAlp Dener .  J    - Matrix used for the jacobian
48847450a7bSBarry Smith .  Jpre - Matrix that will be used to construct the preconditioner, can be same as `J`
4894a48860cSAlp Dener .  func - Jacobian evaluation routine
4904a48860cSAlp Dener -  ctx  - [optional] user-defined context for private data for the
49147450a7bSBarry Smith           Jacobian evaluation routine (may be `NULL`)
4924a48860cSAlp Dener 
49320f4b53cSBarry Smith    Calling sequence of `func`:
49420f4b53cSBarry Smith $  PetscErrorCode func(Tao tao, Vec x, Mat J, Mat Jpre, void *ctx);
49547450a7bSBarry Smith +  tao  - the `Tao`  context
4964a48860cSAlp Dener .  x    - input vector
4974a48860cSAlp Dener .  J    - Jacobian matrix
49847450a7bSBarry Smith .  Jpre - matrix used to construct the preconditioner, usually the same as `J`
4994a48860cSAlp Dener -  ctx  - [optional] user-defined Jacobian context
5004a48860cSAlp Dener 
5014a48860cSAlp Dener    Level: intermediate
50265ba42b6SBarry Smith 
503*1cc06b55SBarry Smith .seealso: [](ch_tao), `Tao`, `TaoSetGradient()`, `TaoSetObjective()`
5044a48860cSAlp Dener @*/
505d71ae5a4SJacob Faibussowitsch PetscErrorCode TaoSetJacobianResidualRoutine(Tao tao, Mat J, Mat Jpre, PetscErrorCode (*func)(Tao, Vec, Mat, Mat, void *), void *ctx)
506d71ae5a4SJacob Faibussowitsch {
5074a48860cSAlp Dener   PetscFunctionBegin;
5084a48860cSAlp Dener   PetscValidHeaderSpecific(tao, TAO_CLASSID, 1);
5094a48860cSAlp Dener   if (J) {
5104a48860cSAlp Dener     PetscValidHeaderSpecific(J, MAT_CLASSID, 2);
5114a48860cSAlp Dener     PetscCheckSameComm(tao, 1, J, 2);
5124a48860cSAlp Dener   }
5134a48860cSAlp Dener   if (Jpre) {
5144a48860cSAlp Dener     PetscValidHeaderSpecific(Jpre, MAT_CLASSID, 3);
5154a48860cSAlp Dener     PetscCheckSameComm(tao, 1, Jpre, 3);
5164a48860cSAlp Dener   }
517ad540459SPierre Jolivet   if (ctx) tao->user_lsjacP = ctx;
518ad540459SPierre Jolivet   if (func) tao->ops->computeresidualjacobian = func;
5194a48860cSAlp Dener   if (J) {
5209566063dSJacob Faibussowitsch     PetscCall(PetscObjectReference((PetscObject)J));
5219566063dSJacob Faibussowitsch     PetscCall(MatDestroy(&tao->ls_jac));
5224a48860cSAlp Dener     tao->ls_jac = J;
5234a48860cSAlp Dener   }
5244a48860cSAlp Dener   if (Jpre) {
5259566063dSJacob Faibussowitsch     PetscCall(PetscObjectReference((PetscObject)Jpre));
5269566063dSJacob Faibussowitsch     PetscCall(MatDestroy(&tao->ls_jac_pre));
5274a48860cSAlp Dener     tao->ls_jac_pre = Jpre;
5284a48860cSAlp Dener   }
5293ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
5304a48860cSAlp Dener }
5314a48860cSAlp Dener 
5324a48860cSAlp Dener /*@C
533a7e14dcfSSatish Balay    TaoSetJacobianStateRoutine - Sets the function to compute the Jacobian
534a7e14dcfSSatish Balay    (and its inverse) of the constraint function with respect to the state variables.
53565ba42b6SBarry Smith    Used only for PDE-constrained optimization.
536a7e14dcfSSatish Balay 
53720f4b53cSBarry Smith    Logically Collective
538a7e14dcfSSatish Balay 
539a7e14dcfSSatish Balay    Input Parameters:
54047450a7bSBarry Smith +  tao  - the `Tao` context
54147450a7bSBarry Smith .  J    - Matrix used for the Jacobian
54247450a7bSBarry Smith .  Jpre - Matrix that will be used to construct the preconditioner, can be same as `J`.  Only used if `Jinv` is `NULL`
54347450a7bSBarry 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.
544f4c1ad5cSStefano Zampini .  func - Jacobian evaluation routine
545a7e14dcfSSatish Balay -  ctx  - [optional] user-defined context for private data for the
54647450a7bSBarry Smith           Jacobian evaluation routine (may be `NULL`)
547a7e14dcfSSatish Balay 
54820f4b53cSBarry Smith    Calling sequence of `func`:
54920f4b53cSBarry Smith $   PetscErrorCode func(Tao tao, Vec x, Mat J, Mat Jpre, Mat Jinv, void *ctx);
55047450a7bSBarry Smith +  tao  - the `Tao` context
551a7e14dcfSSatish Balay .  x    - input vector
552a7e14dcfSSatish Balay .  J    - Jacobian matrix
55347450a7bSBarry Smith .  Jpre - matrix used to construct the preconditioner, usually the same as `J`
55420f4b53cSBarry Smith .  Jinv - inverse of `J`
555a7e14dcfSSatish Balay -  ctx  - [optional] user-defined Jacobian context
556a7e14dcfSSatish Balay 
557a7e14dcfSSatish Balay    Level: intermediate
55865ba42b6SBarry Smith 
559*1cc06b55SBarry Smith .seealso: [](ch_tao), `Tao`, `TaoComputeJacobianState()`, `TaoSetJacobianDesignRoutine()`, `TaoSetStateDesignIS()`
560a7e14dcfSSatish Balay @*/
561d71ae5a4SJacob Faibussowitsch PetscErrorCode TaoSetJacobianStateRoutine(Tao tao, Mat J, Mat Jpre, Mat Jinv, PetscErrorCode (*func)(Tao, Vec, Mat, Mat, Mat, void *), void *ctx)
562d71ae5a4SJacob Faibussowitsch {
563a7e14dcfSSatish Balay   PetscFunctionBegin;
564441846f8SBarry Smith   PetscValidHeaderSpecific(tao, TAO_CLASSID, 1);
565a7e14dcfSSatish Balay   if (J) {
566a7e14dcfSSatish Balay     PetscValidHeaderSpecific(J, MAT_CLASSID, 2);
567a7e14dcfSSatish Balay     PetscCheckSameComm(tao, 1, J, 2);
568a7e14dcfSSatish Balay   }
569a7e14dcfSSatish Balay   if (Jpre) {
570a7e14dcfSSatish Balay     PetscValidHeaderSpecific(Jpre, MAT_CLASSID, 3);
571a7e14dcfSSatish Balay     PetscCheckSameComm(tao, 1, Jpre, 3);
572a7e14dcfSSatish Balay   }
573a7e14dcfSSatish Balay   if (Jinv) {
574a7e14dcfSSatish Balay     PetscValidHeaderSpecific(Jinv, MAT_CLASSID, 4);
575a7e14dcfSSatish Balay     PetscCheckSameComm(tao, 1, Jinv, 4);
576a7e14dcfSSatish Balay   }
577ad540459SPierre Jolivet   if (ctx) tao->user_jac_stateP = ctx;
578ad540459SPierre Jolivet   if (func) tao->ops->computejacobianstate = func;
579a7e14dcfSSatish Balay   if (J) {
5809566063dSJacob Faibussowitsch     PetscCall(PetscObjectReference((PetscObject)J));
5819566063dSJacob Faibussowitsch     PetscCall(MatDestroy(&tao->jacobian_state));
582a7e14dcfSSatish Balay     tao->jacobian_state = J;
583a7e14dcfSSatish Balay   }
584a7e14dcfSSatish Balay   if (Jpre) {
5859566063dSJacob Faibussowitsch     PetscCall(PetscObjectReference((PetscObject)Jpre));
5869566063dSJacob Faibussowitsch     PetscCall(MatDestroy(&tao->jacobian_state_pre));
587a7e14dcfSSatish Balay     tao->jacobian_state_pre = Jpre;
588a7e14dcfSSatish Balay   }
589a7e14dcfSSatish Balay   if (Jinv) {
5909566063dSJacob Faibussowitsch     PetscCall(PetscObjectReference((PetscObject)Jinv));
5919566063dSJacob Faibussowitsch     PetscCall(MatDestroy(&tao->jacobian_state_inv));
592a7e14dcfSSatish Balay     tao->jacobian_state_inv = Jinv;
593a7e14dcfSSatish Balay   }
5943ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
595a7e14dcfSSatish Balay }
596a7e14dcfSSatish Balay 
597a7e14dcfSSatish Balay /*@C
598a7e14dcfSSatish Balay    TaoSetJacobianDesignRoutine - Sets the function to compute the Jacobian of
599a7e14dcfSSatish Balay    the constraint function with respect to the design variables.  Used only for
60065ba42b6SBarry Smith    PDE-constrained optimization.
601a7e14dcfSSatish Balay 
60220f4b53cSBarry Smith    Logically Collective
603a7e14dcfSSatish Balay 
604a7e14dcfSSatish Balay    Input Parameters:
60547450a7bSBarry Smith +  tao  - the `Tao` context
60647450a7bSBarry Smith .  J    - Matrix used for the Jacobian
607f4c1ad5cSStefano Zampini .  func - Jacobian evaluation routine
608a7e14dcfSSatish Balay -  ctx  - [optional] user-defined context for private data for the
60947450a7bSBarry Smith           Jacobian evaluation routine (may be `NULL`)
610a7e14dcfSSatish Balay 
61120f4b53cSBarry Smith    Calling sequence of `func`:
61220f4b53cSBarry Smith $  PetscErrorCode func(Tao tao, Vec x, Mat J, void *ctx);
61347450a7bSBarry Smith +  tao - the `Tao` context
614a7e14dcfSSatish Balay .  x   - input vector
615a7e14dcfSSatish Balay .  J   - Jacobian matrix
616a7e14dcfSSatish Balay -  ctx - [optional] user-defined Jacobian context
617a7e14dcfSSatish Balay 
618a7e14dcfSSatish Balay    Level: intermediate
619f4c1ad5cSStefano Zampini 
620*1cc06b55SBarry Smith .seealso: [](ch_tao), `Tao`, `TaoComputeJacobianDesign()`, `TaoSetJacobianStateRoutine()`, `TaoSetStateDesignIS()`
621a7e14dcfSSatish Balay @*/
622d71ae5a4SJacob Faibussowitsch PetscErrorCode TaoSetJacobianDesignRoutine(Tao tao, Mat J, PetscErrorCode (*func)(Tao, Vec, Mat, void *), void *ctx)
623d71ae5a4SJacob Faibussowitsch {
624a7e14dcfSSatish Balay   PetscFunctionBegin;
625441846f8SBarry Smith   PetscValidHeaderSpecific(tao, TAO_CLASSID, 1);
626a7e14dcfSSatish Balay   if (J) {
627a7e14dcfSSatish Balay     PetscValidHeaderSpecific(J, MAT_CLASSID, 2);
628a7e14dcfSSatish Balay     PetscCheckSameComm(tao, 1, J, 2);
629a7e14dcfSSatish Balay   }
630ad540459SPierre Jolivet   if (ctx) tao->user_jac_designP = ctx;
631ad540459SPierre Jolivet   if (func) tao->ops->computejacobiandesign = func;
632a7e14dcfSSatish Balay   if (J) {
6339566063dSJacob Faibussowitsch     PetscCall(PetscObjectReference((PetscObject)J));
6349566063dSJacob Faibussowitsch     PetscCall(MatDestroy(&tao->jacobian_design));
635a7e14dcfSSatish Balay     tao->jacobian_design = J;
636a7e14dcfSSatish Balay   }
6373ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
638a7e14dcfSSatish Balay }
639a7e14dcfSSatish Balay 
640a7e14dcfSSatish Balay /*@
64147450a7bSBarry Smith    TaoSetStateDesignIS - Indicate to the `Tao` object which variables in the
642a7e14dcfSSatish Balay    solution vector are state variables and which are design.  Only applies to
64365ba42b6SBarry Smith    PDE-constrained optimization.
644a7e14dcfSSatish Balay 
645c3339decSBarry Smith    Logically Collective
646a7e14dcfSSatish Balay 
647a7e14dcfSSatish Balay    Input Parameters:
64847450a7bSBarry Smith +  tao  - The `Tao` context
649a7e14dcfSSatish Balay .  s_is - the index set corresponding to the state variables
650a7e14dcfSSatish Balay -  d_is - the index set corresponding to the design variables
651a7e14dcfSSatish Balay 
652a7e14dcfSSatish Balay    Level: intermediate
653a7e14dcfSSatish Balay 
654*1cc06b55SBarry Smith .seealso: [](ch_tao), `Tao`, `TaoSetJacobianStateRoutine()`, `TaoSetJacobianDesignRoutine()`
655a7e14dcfSSatish Balay @*/
656d71ae5a4SJacob Faibussowitsch PetscErrorCode TaoSetStateDesignIS(Tao tao, IS s_is, IS d_is)
657d71ae5a4SJacob Faibussowitsch {
65845cf516eSBarry Smith   PetscFunctionBegin;
6599566063dSJacob Faibussowitsch   PetscCall(PetscObjectReference((PetscObject)s_is));
6609566063dSJacob Faibussowitsch   PetscCall(ISDestroy(&tao->state_is));
661a7e14dcfSSatish Balay   tao->state_is = s_is;
6629566063dSJacob Faibussowitsch   PetscCall(PetscObjectReference((PetscObject)(d_is)));
6639566063dSJacob Faibussowitsch   PetscCall(ISDestroy(&tao->design_is));
664a7e14dcfSSatish Balay   tao->design_is = d_is;
6653ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
666a7e14dcfSSatish Balay }
667a7e14dcfSSatish Balay 
668a7e14dcfSSatish Balay /*@C
669a7e14dcfSSatish Balay    TaoComputeJacobianEquality - Computes the Jacobian matrix that has been
67065ba42b6SBarry Smith    set with `TaoSetJacobianEqualityRoutine()`.
671a7e14dcfSSatish Balay 
672c3339decSBarry Smith    Collective
673a7e14dcfSSatish Balay 
674a7e14dcfSSatish Balay    Input Parameters:
67547450a7bSBarry Smith +  tao - the `Tao` solver context
676f4c1ad5cSStefano Zampini -  X   - input vector
677a7e14dcfSSatish Balay 
678a7e14dcfSSatish Balay    Output Parameters:
679f4c1ad5cSStefano Zampini +  J    - Jacobian matrix
68047450a7bSBarry Smith -  Jpre - matrix used to construct the preconditioner, often the same as `J`
68147450a7bSBarry Smith 
68247450a7bSBarry Smith    Level: developer
683a7e14dcfSSatish Balay 
684a7e14dcfSSatish Balay    Notes:
685a7e14dcfSSatish Balay    Most users should not need to explicitly call this routine, as it
68665ba42b6SBarry Smith    is used internally within the optimization algorithms.
687a7e14dcfSSatish Balay 
688*1cc06b55SBarry Smith .seealso: [](ch_tao), `TaoComputeObjective()`, `TaoComputeObjectiveAndGradient()`, `TaoSetJacobianStateRoutine()`, `TaoComputeJacobianDesign()`, `TaoSetStateDesignIS()`
689a7e14dcfSSatish Balay @*/
690d71ae5a4SJacob Faibussowitsch PetscErrorCode TaoComputeJacobianEquality(Tao tao, Vec X, Mat J, Mat Jpre)
691d71ae5a4SJacob Faibussowitsch {
692a7e14dcfSSatish Balay   PetscFunctionBegin;
693441846f8SBarry Smith   PetscValidHeaderSpecific(tao, TAO_CLASSID, 1);
694a7e14dcfSSatish Balay   PetscValidHeaderSpecific(X, VEC_CLASSID, 2);
695a7e14dcfSSatish Balay   PetscCheckSameComm(tao, 1, X, 2);
696a7e14dcfSSatish Balay   ++tao->njac_equality;
6979566063dSJacob Faibussowitsch   PetscCall(VecLockReadPush(X));
6989566063dSJacob Faibussowitsch   PetscCall(PetscLogEventBegin(TAO_JacobianEval, tao, X, J, Jpre));
699792fecdfSBarry Smith   PetscCallBack("Tao callback Jacobian(equality)", (*tao->ops->computejacobianequality)(tao, X, J, Jpre, tao->user_jac_equalityP));
7009566063dSJacob Faibussowitsch   PetscCall(PetscLogEventEnd(TAO_JacobianEval, tao, X, J, Jpre));
7019566063dSJacob Faibussowitsch   PetscCall(VecLockReadPop(X));
7023ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
703a7e14dcfSSatish Balay }
704a7e14dcfSSatish Balay 
705a7e14dcfSSatish Balay /*@C
706a7e14dcfSSatish Balay    TaoComputeJacobianInequality - Computes the Jacobian matrix that has been
70765ba42b6SBarry Smith    set with `TaoSetJacobianInequalityRoutine()`.
708a7e14dcfSSatish Balay 
709c3339decSBarry Smith    Collective
710a7e14dcfSSatish Balay 
711a7e14dcfSSatish Balay    Input Parameters:
71247450a7bSBarry Smith +  tao - the `Tao` solver context
713f4c1ad5cSStefano Zampini -  X   - input vector
714a7e14dcfSSatish Balay 
715a7e14dcfSSatish Balay    Output Parameters:
716f4c1ad5cSStefano Zampini +  J    - Jacobian matrix
71747450a7bSBarry Smith -  Jpre - matrix used to construct the preconditioner
718a7e14dcfSSatish Balay 
719a7e14dcfSSatish Balay    Level: developer
720a7e14dcfSSatish Balay 
72147450a7bSBarry Smith    Note:
72247450a7bSBarry Smith    Most users should not need to explicitly call this routine, as it
72347450a7bSBarry Smith    is used internally within the minimization solvers.
72447450a7bSBarry Smith 
725*1cc06b55SBarry Smith .seealso: [](ch_tao), `Tao`, `TaoComputeObjective()`, `TaoComputeObjectiveAndGradient()`, `TaoSetJacobianStateRoutine()`, `TaoComputeJacobianDesign()`, `TaoSetStateDesignIS()`
726a7e14dcfSSatish Balay @*/
727d71ae5a4SJacob Faibussowitsch PetscErrorCode TaoComputeJacobianInequality(Tao tao, Vec X, Mat J, Mat Jpre)
728d71ae5a4SJacob Faibussowitsch {
729a7e14dcfSSatish Balay   PetscFunctionBegin;
730441846f8SBarry Smith   PetscValidHeaderSpecific(tao, TAO_CLASSID, 1);
731a7e14dcfSSatish Balay   PetscValidHeaderSpecific(X, VEC_CLASSID, 2);
732a7e14dcfSSatish Balay   PetscCheckSameComm(tao, 1, X, 2);
733a7e14dcfSSatish Balay   ++tao->njac_inequality;
7349566063dSJacob Faibussowitsch   PetscCall(VecLockReadPush(X));
7359566063dSJacob Faibussowitsch   PetscCall(PetscLogEventBegin(TAO_JacobianEval, tao, X, J, Jpre));
736792fecdfSBarry Smith   PetscCallBack("Tao callback Jacobian (inequality)", (*tao->ops->computejacobianinequality)(tao, X, J, Jpre, tao->user_jac_inequalityP));
7379566063dSJacob Faibussowitsch   PetscCall(PetscLogEventEnd(TAO_JacobianEval, tao, X, J, Jpre));
7389566063dSJacob Faibussowitsch   PetscCall(VecLockReadPop(X));
7393ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
740a7e14dcfSSatish Balay }
741a7e14dcfSSatish Balay 
742a7e14dcfSSatish Balay /*@C
743a7e14dcfSSatish Balay    TaoSetJacobianEqualityRoutine - Sets the function to compute the Jacobian
744a7e14dcfSSatish Balay    (and its inverse) of the constraint function with respect to the equality variables.
74565ba42b6SBarry Smith    Used only for PDE-constrained optimization.
746a7e14dcfSSatish Balay 
74720f4b53cSBarry Smith    Logically Collective
748a7e14dcfSSatish Balay 
749a7e14dcfSSatish Balay    Input Parameters:
75047450a7bSBarry Smith +  tao  - the `Tao` context
75147450a7bSBarry Smith .  J    - Matrix used for the Jacobian
75247450a7bSBarry Smith .  Jpre - Matrix that will be used to construct the preconditioner, can be same as `J`.
753f4c1ad5cSStefano Zampini .  func - Jacobian evaluation routine
754a7e14dcfSSatish Balay -  ctx  - [optional] user-defined context for private data for the
75547450a7bSBarry Smith           Jacobian evaluation routine (may be `NULL`)
756a7e14dcfSSatish Balay 
75720f4b53cSBarry Smith    Calling sequence of `func`:
75820f4b53cSBarry Smith $  PetscErrorCode func(Tao tao, Vec x, Mat J, Mat Jpre, void *ctx)
75947450a7bSBarry Smith +  tao  - the `Tao` context
760a7e14dcfSSatish Balay .  x    - input vector
761a7e14dcfSSatish Balay .  J    - Jacobian matrix
76247450a7bSBarry Smith .  Jpre - matrix used to construct the preconditioner, usually the same as `J`
763a7e14dcfSSatish Balay -  ctx  - [optional] user-defined Jacobian context
764a7e14dcfSSatish Balay 
765a7e14dcfSSatish Balay    Level: intermediate
766f4c1ad5cSStefano Zampini 
767*1cc06b55SBarry Smith .seealso: [](ch_tao), `Tao`, `TaoComputeJacobianEquality()`, `TaoSetJacobianDesignRoutine()`, `TaoSetEqualityDesignIS()`
768a7e14dcfSSatish Balay @*/
769d71ae5a4SJacob Faibussowitsch PetscErrorCode TaoSetJacobianEqualityRoutine(Tao tao, Mat J, Mat Jpre, PetscErrorCode (*func)(Tao, Vec, Mat, Mat, void *), void *ctx)
770d71ae5a4SJacob Faibussowitsch {
771a7e14dcfSSatish Balay   PetscFunctionBegin;
772441846f8SBarry Smith   PetscValidHeaderSpecific(tao, TAO_CLASSID, 1);
773a7e14dcfSSatish Balay   if (J) {
774a7e14dcfSSatish Balay     PetscValidHeaderSpecific(J, MAT_CLASSID, 2);
775a7e14dcfSSatish Balay     PetscCheckSameComm(tao, 1, J, 2);
776a7e14dcfSSatish Balay   }
777a7e14dcfSSatish Balay   if (Jpre) {
778a7e14dcfSSatish Balay     PetscValidHeaderSpecific(Jpre, MAT_CLASSID, 3);
779a7e14dcfSSatish Balay     PetscCheckSameComm(tao, 1, Jpre, 3);
780a7e14dcfSSatish Balay   }
781ad540459SPierre Jolivet   if (ctx) tao->user_jac_equalityP = ctx;
782ad540459SPierre Jolivet   if (func) tao->ops->computejacobianequality = func;
783a7e14dcfSSatish Balay   if (J) {
7849566063dSJacob Faibussowitsch     PetscCall(PetscObjectReference((PetscObject)J));
7859566063dSJacob Faibussowitsch     PetscCall(MatDestroy(&tao->jacobian_equality));
786a7e14dcfSSatish Balay     tao->jacobian_equality = J;
787a7e14dcfSSatish Balay   }
788a7e14dcfSSatish Balay   if (Jpre) {
7899566063dSJacob Faibussowitsch     PetscCall(PetscObjectReference((PetscObject)Jpre));
7909566063dSJacob Faibussowitsch     PetscCall(MatDestroy(&tao->jacobian_equality_pre));
791a7e14dcfSSatish Balay     tao->jacobian_equality_pre = Jpre;
792a7e14dcfSSatish Balay   }
7933ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
794a7e14dcfSSatish Balay }
795a7e14dcfSSatish Balay 
796a7e14dcfSSatish Balay /*@C
797a7e14dcfSSatish Balay    TaoSetJacobianInequalityRoutine - Sets the function to compute the Jacobian
798a7e14dcfSSatish Balay    (and its inverse) of the constraint function with respect to the inequality variables.
79965ba42b6SBarry Smith    Used only for PDE-constrained optimization.
800a7e14dcfSSatish Balay 
80120f4b53cSBarry Smith    Logically Collective
802a7e14dcfSSatish Balay 
803a7e14dcfSSatish Balay    Input Parameters:
80447450a7bSBarry Smith +  tao  - the `Tao` context
80547450a7bSBarry Smith .  J    - Matrix used for the Jacobian
80647450a7bSBarry Smith .  Jpre - Matrix that will be used to construct the preconditioner, can be same as `J`.
807f4c1ad5cSStefano Zampini .  func - Jacobian evaluation routine
808a7e14dcfSSatish Balay -  ctx  - [optional] user-defined context for private data for the
80947450a7bSBarry Smith           Jacobian evaluation routine (may be `NULL`)
810a7e14dcfSSatish Balay 
81120f4b53cSBarry Smith    Calling sequence of `func`:
81220f4b53cSBarry Smith $  PetscErrorCode func(Tao tao, Vec x, Mat J, Mat Jpre, void *ctx);
81347450a7bSBarry Smith +  tao  - the `Tao` context
814a7e14dcfSSatish Balay .  x    - input vector
815a7e14dcfSSatish Balay .  J    - Jacobian matrix
81647450a7bSBarry Smith .  Jpre - matrix used to construct the preconditioner, usually the same as `J`
817a7e14dcfSSatish Balay -  ctx  - [optional] user-defined Jacobian context
818a7e14dcfSSatish Balay 
819a7e14dcfSSatish Balay    Level: intermediate
820f4c1ad5cSStefano Zampini 
821*1cc06b55SBarry Smith .seealso: [](ch_tao), `Tao`, `TaoComputeJacobianInequality()`, `TaoSetJacobianDesignRoutine()`, `TaoSetInequalityDesignIS()`
822a7e14dcfSSatish Balay @*/
823d71ae5a4SJacob Faibussowitsch PetscErrorCode TaoSetJacobianInequalityRoutine(Tao tao, Mat J, Mat Jpre, PetscErrorCode (*func)(Tao, Vec, Mat, Mat, void *), void *ctx)
824d71ae5a4SJacob Faibussowitsch {
825a7e14dcfSSatish Balay   PetscFunctionBegin;
826441846f8SBarry Smith   PetscValidHeaderSpecific(tao, TAO_CLASSID, 1);
827a7e14dcfSSatish Balay   if (J) {
828a7e14dcfSSatish Balay     PetscValidHeaderSpecific(J, MAT_CLASSID, 2);
829a7e14dcfSSatish Balay     PetscCheckSameComm(tao, 1, J, 2);
830a7e14dcfSSatish Balay   }
831a7e14dcfSSatish Balay   if (Jpre) {
832a7e14dcfSSatish Balay     PetscValidHeaderSpecific(Jpre, MAT_CLASSID, 3);
833a7e14dcfSSatish Balay     PetscCheckSameComm(tao, 1, Jpre, 3);
834a7e14dcfSSatish Balay   }
835ad540459SPierre Jolivet   if (ctx) tao->user_jac_inequalityP = ctx;
836ad540459SPierre Jolivet   if (func) tao->ops->computejacobianinequality = func;
837a7e14dcfSSatish Balay   if (J) {
8389566063dSJacob Faibussowitsch     PetscCall(PetscObjectReference((PetscObject)J));
8399566063dSJacob Faibussowitsch     PetscCall(MatDestroy(&tao->jacobian_inequality));
840a7e14dcfSSatish Balay     tao->jacobian_inequality = J;
841a7e14dcfSSatish Balay   }
842a7e14dcfSSatish Balay   if (Jpre) {
8439566063dSJacob Faibussowitsch     PetscCall(PetscObjectReference((PetscObject)Jpre));
8449566063dSJacob Faibussowitsch     PetscCall(MatDestroy(&tao->jacobian_inequality_pre));
845a7e14dcfSSatish Balay     tao->jacobian_inequality_pre = Jpre;
846a7e14dcfSSatish Balay   }
8473ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
848a7e14dcfSSatish Balay }
849