xref: /petsc/src/tao/interface/taosolver_hj.c (revision 47450a7baf26d24688d7bf4590d13280814a31c3)
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 
6c3339decSBarry Smith    Logically collective
7a7e14dcfSSatish Balay 
8a7e14dcfSSatish Balay    Input Parameters:
9*47450a7bSBarry Smith +  tao  - the `Tao` context
10a7e14dcfSSatish Balay .  H    - Matrix used for the hessian
11*47450a7bSBarry 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
14*47450a7bSBarry 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
22*47450a7bSBarry Smith .  Hpre - matrix used to construct the preconditioner, usually the same as `H`
23a7e14dcfSSatish Balay -  ctx  - [optional] user-defined Hessian context
24a7e14dcfSSatish Balay 
25a7e14dcfSSatish Balay    Level: beginner
26a82e8c82SStefano Zampini 
27*47450a7bSBarry Smith .seealso: [](chapter_tao), `Tao`, `TaoTypes`, `TaoSetObjective()`, `TaoSetGradient()`, `TaoSetObjectiveAndGradient()`, `TaoGetHessian()`
28a7e14dcfSSatish Balay @*/
29d71ae5a4SJacob Faibussowitsch PetscErrorCode TaoSetHessian(Tao tao, Mat H, Mat Hpre, PetscErrorCode (*func)(Tao, Vec, Mat, Mat, void *), void *ctx)
30d71ae5a4SJacob Faibussowitsch {
31a7e14dcfSSatish Balay   PetscFunctionBegin;
32441846f8SBarry Smith   PetscValidHeaderSpecific(tao, TAO_CLASSID, 1);
33a7e14dcfSSatish Balay   if (H) {
34a7e14dcfSSatish Balay     PetscValidHeaderSpecific(H, MAT_CLASSID, 2);
35a7e14dcfSSatish Balay     PetscCheckSameComm(tao, 1, H, 2);
36a7e14dcfSSatish Balay   }
37a7e14dcfSSatish Balay   if (Hpre) {
38a7e14dcfSSatish Balay     PetscValidHeaderSpecific(Hpre, MAT_CLASSID, 3);
39a7e14dcfSSatish Balay     PetscCheckSameComm(tao, 1, Hpre, 3);
40a7e14dcfSSatish Balay   }
41a82e8c82SStefano Zampini   if (ctx) tao->user_hessP = ctx;
42a82e8c82SStefano Zampini   if (func) tao->ops->computehessian = func;
43a7e14dcfSSatish Balay   if (H) {
449566063dSJacob Faibussowitsch     PetscCall(PetscObjectReference((PetscObject)H));
459566063dSJacob Faibussowitsch     PetscCall(MatDestroy(&tao->hessian));
46a7e14dcfSSatish Balay     tao->hessian = H;
47a7e14dcfSSatish Balay   }
48a7e14dcfSSatish Balay   if (Hpre) {
499566063dSJacob Faibussowitsch     PetscCall(PetscObjectReference((PetscObject)Hpre));
509566063dSJacob Faibussowitsch     PetscCall(MatDestroy(&tao->hessian_pre));
51a7e14dcfSSatish Balay     tao->hessian_pre = Hpre;
52a7e14dcfSSatish Balay   }
533ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
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:
62*47450a7bSBarry Smith .  tao  - the `Tao` context
63a82e8c82SStefano Zampini 
64a82e8c82SStefano Zampini    OutputParameters:
65a82e8c82SStefano Zampini +  H    - Matrix used for the hessian
66*47450a7bSBarry Smith .  Hpre - Matrix that will be used to construct the 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
76*47450a7bSBarry Smith .  Hpre - matrix used to construct the preconditioner, usually the same as `H`
77a82e8c82SStefano Zampini -  ctx  - [optional] user-defined Hessian context
78a82e8c82SStefano Zampini 
79a82e8c82SStefano Zampini    Level: beginner
80a82e8c82SStefano Zampini 
81*47450a7bSBarry Smith .seealso: [](chapter_tao), `Tao`, TaoType`, `TaoGetObjective()`, `TaoGetGradient()`, `TaoGetObjectiveAndGradient()`, `TaoSetHessian()`
82a82e8c82SStefano Zampini @*/
83d71ae5a4SJacob Faibussowitsch PetscErrorCode TaoGetHessian(Tao tao, Mat *H, Mat *Hpre, PetscErrorCode (**func)(Tao, Vec, Mat, Mat, void *), void **ctx)
84d71ae5a4SJacob Faibussowitsch {
85a82e8c82SStefano Zampini   PetscFunctionBegin;
86a82e8c82SStefano Zampini   PetscValidHeaderSpecific(tao, TAO_CLASSID, 1);
87a82e8c82SStefano Zampini   if (H) *H = tao->hessian;
88a82e8c82SStefano Zampini   if (Hpre) *Hpre = tao->hessian_pre;
89a82e8c82SStefano Zampini   if (ctx) *ctx = tao->user_hessP;
90a82e8c82SStefano Zampini   if (func) *func = tao->ops->computehessian;
913ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
92a82e8c82SStefano Zampini }
93a82e8c82SStefano Zampini 
94d71ae5a4SJacob Faibussowitsch PetscErrorCode TaoTestHessian(Tao tao)
95d71ae5a4SJacob Faibussowitsch {
9609baa881SHong Zhang   Mat               A, B, C, D, hessian;
9709baa881SHong Zhang   Vec               x = tao->solution;
9809baa881SHong Zhang   PetscReal         nrm, gnorm;
9909baa881SHong Zhang   PetscReal         threshold = 1.e-5;
10009baa881SHong Zhang   PetscInt          m, n, M, N;
10109baa881SHong Zhang   PetscBool         complete_print = PETSC_FALSE, test = PETSC_FALSE, flg;
102f49d1c87SHong Zhang   PetscViewer       viewer, mviewer;
10309baa881SHong Zhang   MPI_Comm          comm;
10409baa881SHong Zhang   PetscInt          tabs;
10509baa881SHong Zhang   static PetscBool  directionsprinted = PETSC_FALSE;
106f49d1c87SHong Zhang   PetscViewerFormat format;
10709baa881SHong Zhang 
10809baa881SHong Zhang   PetscFunctionBegin;
109d0609cedSBarry Smith   PetscObjectOptionsBegin((PetscObject)tao);
1109566063dSJacob Faibussowitsch   PetscCall(PetscOptionsName("-tao_test_hessian", "Compare hand-coded and finite difference Hessians", "None", &test));
1119566063dSJacob Faibussowitsch   PetscCall(PetscOptionsReal("-tao_test_hessian", "Threshold for element difference between hand-coded and finite difference being meaningful", "None", threshold, &threshold, NULL));
1129566063dSJacob Faibussowitsch   PetscCall(PetscOptionsViewer("-tao_test_hessian_view", "View difference between hand-coded and finite difference Hessians element entries", "None", &mviewer, &format, &complete_print));
113d0609cedSBarry Smith   PetscOptionsEnd();
1143ba16761SJacob Faibussowitsch   if (!test) PetscFunctionReturn(PETSC_SUCCESS);
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));
2173ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
21809baa881SHong Zhang }
21909baa881SHong Zhang 
220a7e14dcfSSatish Balay /*@C
221a7e14dcfSSatish Balay    TaoComputeHessian - Computes the Hessian matrix that has been
22265ba42b6SBarry Smith    set with `TaoSetHessian()`.
223a7e14dcfSSatish Balay 
224c3339decSBarry Smith    Collective
225a7e14dcfSSatish Balay 
226a7e14dcfSSatish Balay    Input Parameters:
227f4c1ad5cSStefano Zampini +  tao - the Tao solver context
228f4c1ad5cSStefano Zampini -  X   - input vector
229a7e14dcfSSatish Balay 
230a7e14dcfSSatish Balay    Output Parameters:
231a7e14dcfSSatish Balay +  H    - Hessian matrix
232aa6c7ce3SBarry Smith -  Hpre - Preconditioning matrix
233a7e14dcfSSatish Balay 
23409baa881SHong Zhang    Options Database Keys:
23509baa881SHong Zhang +     -tao_test_hessian - compare the user provided Hessian with one compute via finite differences to check for errors
23609baa881SHong Zhang .     -tao_test_hessian <numerical value>  - display entries in the difference between the user provided Hessian and finite difference Hessian that are greater than a certain value to help users detect errors
237dfe02fe6SHong Zhang -     -tao_test_hessian_view - display the user provided Hessian, the finite difference Hessian and the difference between them to help users detect the location of errors in the user provided Hessian
23809baa881SHong Zhang 
239*47450a7bSBarry Smith    Level: developer
240*47450a7bSBarry Smith 
241a7e14dcfSSatish Balay    Notes:
242a7e14dcfSSatish Balay    Most users should not need to explicitly call this routine, as it
243a7e14dcfSSatish Balay    is used internally within the minimization solvers.
244a7e14dcfSSatish Balay 
24565ba42b6SBarry Smith    `TaoComputeHessian()` is typically used within optimization algorithms,
24665ba42b6SBarry Smith    so most users would not generally call this routine
247a7e14dcfSSatish Balay    themselves.
248a7e14dcfSSatish Balay 
24965ba42b6SBarry Smith    Developer Note:
25065ba42b6SBarry Smith    The Hessian test mechanism follows `SNESTestJacobian()`.
25109baa881SHong Zhang 
252*47450a7bSBarry Smith .seealso: [](chapter_tao), `Tao`, `TaoComputeObjective()`, `TaoComputeObjectiveAndGradient()`, `TaoSetHessian()`
253a7e14dcfSSatish Balay @*/
254d71ae5a4SJacob Faibussowitsch PetscErrorCode TaoComputeHessian(Tao tao, Vec X, Mat H, Mat Hpre)
255d71ae5a4SJacob Faibussowitsch {
256a7e14dcfSSatish Balay   PetscFunctionBegin;
257441846f8SBarry Smith   PetscValidHeaderSpecific(tao, TAO_CLASSID, 1);
258a7e14dcfSSatish Balay   PetscValidHeaderSpecific(X, VEC_CLASSID, 2);
259a7e14dcfSSatish Balay   PetscCheckSameComm(tao, 1, X, 2);
260794dad8cSStefano Zampini   PetscCheck(tao->ops->computehessian, PetscObjectComm((PetscObject)tao), PETSC_ERR_ARG_WRONGSTATE, "TaoSetHessian() not called");
261794dad8cSStefano Zampini 
262a7e14dcfSSatish Balay   ++tao->nhess;
2639566063dSJacob Faibussowitsch   PetscCall(VecLockReadPush(X));
2649566063dSJacob Faibussowitsch   PetscCall(PetscLogEventBegin(TAO_HessianEval, tao, X, H, Hpre));
265792fecdfSBarry Smith   PetscCallBack("Tao callback Hessian", (*tao->ops->computehessian)(tao, X, H, Hpre, tao->user_hessP));
2669566063dSJacob Faibussowitsch   PetscCall(PetscLogEventEnd(TAO_HessianEval, tao, X, H, Hpre));
2679566063dSJacob Faibussowitsch   PetscCall(VecLockReadPop(X));
26809baa881SHong Zhang 
2699566063dSJacob Faibussowitsch   PetscCall(TaoTestHessian(tao));
2703ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
271a7e14dcfSSatish Balay }
272a7e14dcfSSatish Balay 
273a7e14dcfSSatish Balay /*@C
274a7e14dcfSSatish Balay    TaoComputeJacobian - Computes the Jacobian matrix that has been
275a7e14dcfSSatish Balay    set with TaoSetJacobianRoutine().
276a7e14dcfSSatish Balay 
277c3339decSBarry Smith    Collective
278a7e14dcfSSatish Balay 
279a7e14dcfSSatish Balay    Input Parameters:
280f4c1ad5cSStefano Zampini +  tao - the Tao solver context
281f4c1ad5cSStefano Zampini -  X   - input vector
282a7e14dcfSSatish Balay 
283a7e14dcfSSatish Balay    Output Parameters:
284f4c1ad5cSStefano Zampini +  J    - Jacobian matrix
285f4c1ad5cSStefano Zampini -  Jpre - Preconditioning matrix
286a7e14dcfSSatish Balay 
287*47450a7bSBarry Smith    Level: developer
288*47450a7bSBarry Smith 
289a7e14dcfSSatish Balay    Notes:
290a7e14dcfSSatish Balay    Most users should not need to explicitly call this routine, as it
291a7e14dcfSSatish Balay    is used internally within the minimization solvers.
292a7e14dcfSSatish Balay 
29365ba42b6SBarry Smith    `TaoComputeJacobian()` is typically used within minimization
294a7e14dcfSSatish Balay    implementations, so most users would not generally call this routine
295a7e14dcfSSatish Balay    themselves.
296a7e14dcfSSatish Balay 
297*47450a7bSBarry Smith .seealso: [](chapter_tao), `TaoComputeObjective()`, `TaoComputeObjectiveAndGradient()`, `TaoSetJacobianRoutine()`
298a7e14dcfSSatish Balay @*/
299d71ae5a4SJacob Faibussowitsch PetscErrorCode TaoComputeJacobian(Tao tao, Vec X, Mat J, Mat Jpre)
300d71ae5a4SJacob Faibussowitsch {
301a7e14dcfSSatish Balay   PetscFunctionBegin;
302441846f8SBarry Smith   PetscValidHeaderSpecific(tao, TAO_CLASSID, 1);
303a7e14dcfSSatish Balay   PetscValidHeaderSpecific(X, VEC_CLASSID, 2);
304a7e14dcfSSatish Balay   PetscCheckSameComm(tao, 1, X, 2);
305a7e14dcfSSatish Balay   ++tao->njac;
3069566063dSJacob Faibussowitsch   PetscCall(VecLockReadPush(X));
3079566063dSJacob Faibussowitsch   PetscCall(PetscLogEventBegin(TAO_JacobianEval, tao, X, J, Jpre));
308792fecdfSBarry Smith   PetscCallBack("Tao callback Jacobian", (*tao->ops->computejacobian)(tao, X, J, Jpre, tao->user_jacP));
3099566063dSJacob Faibussowitsch   PetscCall(PetscLogEventEnd(TAO_JacobianEval, tao, X, J, Jpre));
3109566063dSJacob Faibussowitsch   PetscCall(VecLockReadPop(X));
3113ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
312a7e14dcfSSatish Balay }
313a7e14dcfSSatish Balay 
314a7e14dcfSSatish Balay /*@C
3154a48860cSAlp Dener    TaoComputeResidualJacobian - Computes the least-squares residual Jacobian matrix that has been
31665ba42b6SBarry Smith    set with `TaoSetJacobianResidual()`.
3174a48860cSAlp Dener 
318c3339decSBarry Smith    Collective
3194a48860cSAlp Dener 
3204a48860cSAlp Dener    Input Parameters:
3214a48860cSAlp Dener +  tao - the Tao solver context
3224a48860cSAlp Dener -  X   - input vector
3234a48860cSAlp Dener 
3244a48860cSAlp Dener    Output Parameters:
3254a48860cSAlp Dener +  J    - Jacobian matrix
3264a48860cSAlp Dener -  Jpre - Preconditioning matrix
3274a48860cSAlp Dener 
328*47450a7bSBarry Smith    Level: developer
329*47450a7bSBarry Smith 
3304a48860cSAlp Dener    Notes:
3314a48860cSAlp Dener    Most users should not need to explicitly call this routine, as it
3324a48860cSAlp Dener    is used internally within the minimization solvers.
3334a48860cSAlp Dener 
33465ba42b6SBarry Smith    `TaoComputeResidualJacobian()` is typically used within least-squares
3354a48860cSAlp Dener    implementations, so most users would not generally call this routine
3364a48860cSAlp Dener    themselves.
3374a48860cSAlp Dener 
338*47450a7bSBarry Smith .seealso: [](chapter_tao), `Tao`, `TaoComputeResidual()`, `TaoSetJacobianResidual()`
3394a48860cSAlp Dener @*/
340d71ae5a4SJacob Faibussowitsch PetscErrorCode TaoComputeResidualJacobian(Tao tao, Vec X, Mat J, Mat Jpre)
341d71ae5a4SJacob Faibussowitsch {
3424a48860cSAlp Dener   PetscFunctionBegin;
3434a48860cSAlp Dener   PetscValidHeaderSpecific(tao, TAO_CLASSID, 1);
3444a48860cSAlp Dener   PetscValidHeaderSpecific(X, VEC_CLASSID, 2);
3454a48860cSAlp Dener   PetscCheckSameComm(tao, 1, X, 2);
3464a48860cSAlp Dener   ++tao->njac;
3479566063dSJacob Faibussowitsch   PetscCall(VecLockReadPush(X));
3489566063dSJacob Faibussowitsch   PetscCall(PetscLogEventBegin(TAO_JacobianEval, tao, X, J, Jpre));
349792fecdfSBarry Smith   PetscCallBack("Tao callback least-squares residual Jacobian", (*tao->ops->computeresidualjacobian)(tao, X, J, Jpre, tao->user_lsjacP));
3509566063dSJacob Faibussowitsch   PetscCall(PetscLogEventEnd(TAO_JacobianEval, tao, X, J, Jpre));
3519566063dSJacob Faibussowitsch   PetscCall(VecLockReadPop(X));
3523ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
3534a48860cSAlp Dener }
3544a48860cSAlp Dener 
3554a48860cSAlp Dener /*@C
356a7e14dcfSSatish Balay    TaoComputeJacobianState - Computes the Jacobian matrix that has been
35765ba42b6SBarry Smith    set with `TaoSetJacobianStateRoutine()`.
358a7e14dcfSSatish Balay 
359c3339decSBarry Smith    Collective
360a7e14dcfSSatish Balay 
361a7e14dcfSSatish Balay    Input Parameters:
362*47450a7bSBarry Smith +  tao - the `Tao` solver context
363f4c1ad5cSStefano Zampini -  X   - input vector
364a7e14dcfSSatish Balay 
365a7e14dcfSSatish Balay    Output Parameters:
3666b867d5aSJose E. Roman +  J    - Jacobian matrix
367*47450a7bSBarry Smith .  Jpre - matrix used to construct the preconditioner, often the same as `J`
36865ba42b6SBarry Smith -  Jinv - unknown
369a7e14dcfSSatish Balay 
370a7e14dcfSSatish Balay    Level: developer
371a7e14dcfSSatish Balay 
372*47450a7bSBarry Smith    Note:
373*47450a7bSBarry Smith    Most users should not need to explicitly call this routine, as it
374*47450a7bSBarry Smith    is used internally within the optimization algorithms.
375*47450a7bSBarry Smith 
376*47450a7bSBarry Smith .seealso: [](chapter_tao), `Tao`, `TaoComputeObjective()`, `TaoComputeObjectiveAndGradient()`, `TaoSetJacobianStateRoutine()`, `TaoComputeJacobianDesign()`, `TaoSetStateDesignIS()`
377a7e14dcfSSatish Balay @*/
378d71ae5a4SJacob Faibussowitsch PetscErrorCode TaoComputeJacobianState(Tao tao, Vec X, Mat J, Mat Jpre, Mat Jinv)
379d71ae5a4SJacob Faibussowitsch {
380a7e14dcfSSatish Balay   PetscFunctionBegin;
381441846f8SBarry Smith   PetscValidHeaderSpecific(tao, TAO_CLASSID, 1);
382a7e14dcfSSatish Balay   PetscValidHeaderSpecific(X, VEC_CLASSID, 2);
383a7e14dcfSSatish Balay   PetscCheckSameComm(tao, 1, X, 2);
384a7e14dcfSSatish Balay   ++tao->njac_state;
3859566063dSJacob Faibussowitsch   PetscCall(VecLockReadPush(X));
3869566063dSJacob Faibussowitsch   PetscCall(PetscLogEventBegin(TAO_JacobianEval, tao, X, J, Jpre));
387792fecdfSBarry Smith   PetscCallBack("Tao callback Jacobian(state)", (*tao->ops->computejacobianstate)(tao, X, J, Jpre, Jinv, tao->user_jac_stateP));
3889566063dSJacob Faibussowitsch   PetscCall(PetscLogEventEnd(TAO_JacobianEval, tao, X, J, Jpre));
3899566063dSJacob Faibussowitsch   PetscCall(VecLockReadPop(X));
3903ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
391a7e14dcfSSatish Balay }
392a7e14dcfSSatish Balay 
393a7e14dcfSSatish Balay /*@C
394a7e14dcfSSatish Balay    TaoComputeJacobianDesign - Computes the Jacobian matrix that has been
39565ba42b6SBarry Smith    set with `TaoSetJacobianDesignRoutine()`.
396a7e14dcfSSatish Balay 
397c3339decSBarry Smith    Collective
398a7e14dcfSSatish Balay 
399a7e14dcfSSatish Balay    Input Parameters:
400f4c1ad5cSStefano Zampini +  tao - the Tao solver context
401f4c1ad5cSStefano Zampini -  X   - input vector
402a7e14dcfSSatish Balay 
403a7e14dcfSSatish Balay    Output Parameters:
404f4c1ad5cSStefano Zampini .  J - Jacobian matrix
405a7e14dcfSSatish Balay 
406*47450a7bSBarry Smith    Level: developer
407*47450a7bSBarry Smith 
408*47450a7bSBarry Smith    Note:
409a7e14dcfSSatish Balay    Most users should not need to explicitly call this routine, as it
41065ba42b6SBarry Smith    is used internally within the optimization algorithms.
411a7e14dcfSSatish Balay 
412*47450a7bSBarry Smith .seealso: [](chapter_tao), `Tao`, `TaoComputeObjective()`, `TaoComputeObjectiveAndGradient()`, `TaoSetJacobianDesignRoutine()`, `TaoComputeJacobianDesign()`, `TaoSetStateDesignIS()`
413a7e14dcfSSatish Balay @*/
414d71ae5a4SJacob Faibussowitsch PetscErrorCode TaoComputeJacobianDesign(Tao tao, Vec X, Mat J)
415d71ae5a4SJacob Faibussowitsch {
416a7e14dcfSSatish Balay   PetscFunctionBegin;
417441846f8SBarry Smith   PetscValidHeaderSpecific(tao, TAO_CLASSID, 1);
418a7e14dcfSSatish Balay   PetscValidHeaderSpecific(X, VEC_CLASSID, 2);
419a7e14dcfSSatish Balay   PetscCheckSameComm(tao, 1, X, 2);
420a7e14dcfSSatish Balay   ++tao->njac_design;
4219566063dSJacob Faibussowitsch   PetscCall(VecLockReadPush(X));
4229566063dSJacob Faibussowitsch   PetscCall(PetscLogEventBegin(TAO_JacobianEval, tao, X, J, NULL));
423792fecdfSBarry Smith   PetscCallBack("Tao callback Jacobian(design)", (*tao->ops->computejacobiandesign)(tao, X, J, tao->user_jac_designP));
4249566063dSJacob Faibussowitsch   PetscCall(PetscLogEventEnd(TAO_JacobianEval, tao, X, J, NULL));
4259566063dSJacob Faibussowitsch   PetscCall(VecLockReadPop(X));
4263ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
427a7e14dcfSSatish Balay }
428a7e14dcfSSatish Balay 
429a7e14dcfSSatish Balay /*@C
430a7e14dcfSSatish Balay    TaoSetJacobianRoutine - Sets the function to compute the Jacobian as well as the location to store the matrix.
431a7e14dcfSSatish Balay 
432c3339decSBarry Smith    Logically collective
433a7e14dcfSSatish Balay 
434a7e14dcfSSatish Balay    Input Parameters:
435*47450a7bSBarry Smith +  tao  - the `Tao` context
436*47450a7bSBarry Smith .  J    - Matrix used for the Jacobian
437*47450a7bSBarry Smith .  Jpre - Matrix that will be used to construct the preconditioner, can be same as `J`
438f4c1ad5cSStefano Zampini .  func - Jacobian evaluation routine
439a7e14dcfSSatish Balay -  ctx  - [optional] user-defined context for private data for the
440*47450a7bSBarry Smith           Jacobian evaluation routine (may be `NULL`)
441a7e14dcfSSatish Balay 
442f4c1ad5cSStefano Zampini    Calling sequence of func:
443f4c1ad5cSStefano Zampini $    func(Tao tao,Vec x,Mat J,Mat Jpre,void *ctx);
444a7e14dcfSSatish Balay 
445*47450a7bSBarry Smith +  tao  - the `Tao` context
446a7e14dcfSSatish Balay .  x    - input vector
447a7e14dcfSSatish Balay .  J    - Jacobian matrix
448*47450a7bSBarry Smith .  Jpre - matrix used to construct the preconditioner, usually the same as `J`
449a7e14dcfSSatish Balay -  ctx  - [optional] user-defined Jacobian context
450a7e14dcfSSatish Balay 
451a7e14dcfSSatish Balay    Level: intermediate
45265ba42b6SBarry Smith 
453*47450a7bSBarry Smith .seealso: [](chapter_tao), `Tao`, `TaoSetGradient()`, `TaoSetObjective()`
454a7e14dcfSSatish Balay @*/
455d71ae5a4SJacob Faibussowitsch PetscErrorCode TaoSetJacobianRoutine(Tao tao, Mat J, Mat Jpre, PetscErrorCode (*func)(Tao, Vec, Mat, Mat, void *), void *ctx)
456d71ae5a4SJacob Faibussowitsch {
457a7e14dcfSSatish Balay   PetscFunctionBegin;
458441846f8SBarry Smith   PetscValidHeaderSpecific(tao, TAO_CLASSID, 1);
459a7e14dcfSSatish Balay   if (J) {
460a7e14dcfSSatish Balay     PetscValidHeaderSpecific(J, MAT_CLASSID, 2);
461a7e14dcfSSatish Balay     PetscCheckSameComm(tao, 1, J, 2);
462a7e14dcfSSatish Balay   }
463a7e14dcfSSatish Balay   if (Jpre) {
464a7e14dcfSSatish Balay     PetscValidHeaderSpecific(Jpre, MAT_CLASSID, 3);
465a7e14dcfSSatish Balay     PetscCheckSameComm(tao, 1, Jpre, 3);
466a7e14dcfSSatish Balay   }
467ad540459SPierre Jolivet   if (ctx) tao->user_jacP = ctx;
468ad540459SPierre Jolivet   if (func) tao->ops->computejacobian = func;
469a7e14dcfSSatish Balay   if (J) {
4709566063dSJacob Faibussowitsch     PetscCall(PetscObjectReference((PetscObject)J));
4719566063dSJacob Faibussowitsch     PetscCall(MatDestroy(&tao->jacobian));
472a7e14dcfSSatish Balay     tao->jacobian = J;
473a7e14dcfSSatish Balay   }
474a7e14dcfSSatish Balay   if (Jpre) {
4759566063dSJacob Faibussowitsch     PetscCall(PetscObjectReference((PetscObject)Jpre));
4769566063dSJacob Faibussowitsch     PetscCall(MatDestroy(&tao->jacobian_pre));
477a7e14dcfSSatish Balay     tao->jacobian_pre = Jpre;
478a7e14dcfSSatish Balay   }
4793ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
480a7e14dcfSSatish Balay }
481a7e14dcfSSatish Balay 
482a7e14dcfSSatish Balay /*@C
4834ffbe8acSAlp Dener    TaoSetJacobianResidualRoutine - Sets the function to compute the least-squares residual Jacobian as well as the
4844a48860cSAlp Dener    location to store the matrix.
4854a48860cSAlp Dener 
486c3339decSBarry Smith    Logically collective
4874a48860cSAlp Dener 
4884a48860cSAlp Dener    Input Parameters:
489*47450a7bSBarry Smith +  tao  - the `Tao` context
4904a48860cSAlp Dener .  J    - Matrix used for the jacobian
491*47450a7bSBarry Smith .  Jpre - Matrix that will be used to construct the preconditioner, can be same as `J`
4924a48860cSAlp Dener .  func - Jacobian evaluation routine
4934a48860cSAlp Dener -  ctx  - [optional] user-defined context for private data for the
494*47450a7bSBarry Smith           Jacobian evaluation routine (may be `NULL`)
4954a48860cSAlp Dener 
4964a48860cSAlp Dener    Calling sequence of func:
4974a48860cSAlp Dener $    func(Tao tao,Vec x,Mat J,Mat Jpre,void *ctx);
4984a48860cSAlp Dener 
499*47450a7bSBarry Smith +  tao  - the `Tao`  context
5004a48860cSAlp Dener .  x    - input vector
5014a48860cSAlp Dener .  J    - Jacobian matrix
502*47450a7bSBarry Smith .  Jpre - matrix used to construct the preconditioner, usually the same as `J`
5034a48860cSAlp Dener -  ctx  - [optional] user-defined Jacobian context
5044a48860cSAlp Dener 
5054a48860cSAlp Dener    Level: intermediate
50665ba42b6SBarry Smith 
507*47450a7bSBarry Smith .seealso: [](chapter_tao), `Tao`, `TaoSetGradient()`, `TaoSetObjective()`
5084a48860cSAlp Dener @*/
509d71ae5a4SJacob Faibussowitsch PetscErrorCode TaoSetJacobianResidualRoutine(Tao tao, Mat J, Mat Jpre, PetscErrorCode (*func)(Tao, Vec, Mat, Mat, void *), void *ctx)
510d71ae5a4SJacob Faibussowitsch {
5114a48860cSAlp Dener   PetscFunctionBegin;
5124a48860cSAlp Dener   PetscValidHeaderSpecific(tao, TAO_CLASSID, 1);
5134a48860cSAlp Dener   if (J) {
5144a48860cSAlp Dener     PetscValidHeaderSpecific(J, MAT_CLASSID, 2);
5154a48860cSAlp Dener     PetscCheckSameComm(tao, 1, J, 2);
5164a48860cSAlp Dener   }
5174a48860cSAlp Dener   if (Jpre) {
5184a48860cSAlp Dener     PetscValidHeaderSpecific(Jpre, MAT_CLASSID, 3);
5194a48860cSAlp Dener     PetscCheckSameComm(tao, 1, Jpre, 3);
5204a48860cSAlp Dener   }
521ad540459SPierre Jolivet   if (ctx) tao->user_lsjacP = ctx;
522ad540459SPierre Jolivet   if (func) tao->ops->computeresidualjacobian = func;
5234a48860cSAlp Dener   if (J) {
5249566063dSJacob Faibussowitsch     PetscCall(PetscObjectReference((PetscObject)J));
5259566063dSJacob Faibussowitsch     PetscCall(MatDestroy(&tao->ls_jac));
5264a48860cSAlp Dener     tao->ls_jac = J;
5274a48860cSAlp Dener   }
5284a48860cSAlp Dener   if (Jpre) {
5299566063dSJacob Faibussowitsch     PetscCall(PetscObjectReference((PetscObject)Jpre));
5309566063dSJacob Faibussowitsch     PetscCall(MatDestroy(&tao->ls_jac_pre));
5314a48860cSAlp Dener     tao->ls_jac_pre = Jpre;
5324a48860cSAlp Dener   }
5333ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
5344a48860cSAlp Dener }
5354a48860cSAlp Dener 
5364a48860cSAlp Dener /*@C
537a7e14dcfSSatish Balay    TaoSetJacobianStateRoutine - Sets the function to compute the Jacobian
538a7e14dcfSSatish Balay    (and its inverse) of the constraint function with respect to the state variables.
53965ba42b6SBarry Smith    Used only for PDE-constrained optimization.
540a7e14dcfSSatish Balay 
541c3339decSBarry Smith    Logically collective
542a7e14dcfSSatish Balay 
543a7e14dcfSSatish Balay    Input Parameters:
544*47450a7bSBarry Smith +  tao  - the `Tao` context
545*47450a7bSBarry Smith .  J    - Matrix used for the Jacobian
546*47450a7bSBarry Smith .  Jpre - Matrix that will be used to construct the preconditioner, can be same as `J`.  Only used if `Jinv` is `NULL`
547*47450a7bSBarry Smith .  Jinv - [optional] Matrix used to apply the inverse of the state Jacobian. Use `NULL` to default to PETSc `KSP` solvers to apply the inverse.
548f4c1ad5cSStefano Zampini .  func - Jacobian evaluation routine
549a7e14dcfSSatish Balay -  ctx  - [optional] user-defined context for private data for the
550*47450a7bSBarry Smith           Jacobian evaluation routine (may be `NULL`)
551a7e14dcfSSatish Balay 
552f4c1ad5cSStefano Zampini    Calling sequence of func:
553f4c1ad5cSStefano Zampini $    func(Tao tao,Vec x,Mat J,Mat Jpre,Mat Jinv,void *ctx);
554a7e14dcfSSatish Balay 
555*47450a7bSBarry Smith +  tao  - the `Tao` context
556a7e14dcfSSatish Balay .  x    - input vector
557a7e14dcfSSatish Balay .  J    - Jacobian matrix
558*47450a7bSBarry Smith .  Jpre - matrix used to construct the preconditioner, usually the same as `J`
559a7e14dcfSSatish Balay .  Jinv - inverse of J
560a7e14dcfSSatish Balay -  ctx  - [optional] user-defined Jacobian context
561a7e14dcfSSatish Balay 
562a7e14dcfSSatish Balay    Level: intermediate
56365ba42b6SBarry Smith 
564*47450a7bSBarry Smith .seealso: [](chapter_tao), `Tao`, `TaoComputeJacobianState()`, `TaoSetJacobianDesignRoutine()`, `TaoSetStateDesignIS()`
565a7e14dcfSSatish Balay @*/
566d71ae5a4SJacob Faibussowitsch PetscErrorCode TaoSetJacobianStateRoutine(Tao tao, Mat J, Mat Jpre, Mat Jinv, PetscErrorCode (*func)(Tao, Vec, Mat, Mat, Mat, void *), void *ctx)
567d71ae5a4SJacob Faibussowitsch {
568a7e14dcfSSatish Balay   PetscFunctionBegin;
569441846f8SBarry Smith   PetscValidHeaderSpecific(tao, TAO_CLASSID, 1);
570a7e14dcfSSatish Balay   if (J) {
571a7e14dcfSSatish Balay     PetscValidHeaderSpecific(J, MAT_CLASSID, 2);
572a7e14dcfSSatish Balay     PetscCheckSameComm(tao, 1, J, 2);
573a7e14dcfSSatish Balay   }
574a7e14dcfSSatish Balay   if (Jpre) {
575a7e14dcfSSatish Balay     PetscValidHeaderSpecific(Jpre, MAT_CLASSID, 3);
576a7e14dcfSSatish Balay     PetscCheckSameComm(tao, 1, Jpre, 3);
577a7e14dcfSSatish Balay   }
578a7e14dcfSSatish Balay   if (Jinv) {
579a7e14dcfSSatish Balay     PetscValidHeaderSpecific(Jinv, MAT_CLASSID, 4);
580a7e14dcfSSatish Balay     PetscCheckSameComm(tao, 1, Jinv, 4);
581a7e14dcfSSatish Balay   }
582ad540459SPierre Jolivet   if (ctx) tao->user_jac_stateP = ctx;
583ad540459SPierre Jolivet   if (func) tao->ops->computejacobianstate = func;
584a7e14dcfSSatish Balay   if (J) {
5859566063dSJacob Faibussowitsch     PetscCall(PetscObjectReference((PetscObject)J));
5869566063dSJacob Faibussowitsch     PetscCall(MatDestroy(&tao->jacobian_state));
587a7e14dcfSSatish Balay     tao->jacobian_state = J;
588a7e14dcfSSatish Balay   }
589a7e14dcfSSatish Balay   if (Jpre) {
5909566063dSJacob Faibussowitsch     PetscCall(PetscObjectReference((PetscObject)Jpre));
5919566063dSJacob Faibussowitsch     PetscCall(MatDestroy(&tao->jacobian_state_pre));
592a7e14dcfSSatish Balay     tao->jacobian_state_pre = Jpre;
593a7e14dcfSSatish Balay   }
594a7e14dcfSSatish Balay   if (Jinv) {
5959566063dSJacob Faibussowitsch     PetscCall(PetscObjectReference((PetscObject)Jinv));
5969566063dSJacob Faibussowitsch     PetscCall(MatDestroy(&tao->jacobian_state_inv));
597a7e14dcfSSatish Balay     tao->jacobian_state_inv = Jinv;
598a7e14dcfSSatish Balay   }
5993ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
600a7e14dcfSSatish Balay }
601a7e14dcfSSatish Balay 
602a7e14dcfSSatish Balay /*@C
603a7e14dcfSSatish Balay    TaoSetJacobianDesignRoutine - Sets the function to compute the Jacobian of
604a7e14dcfSSatish Balay    the constraint function with respect to the design variables.  Used only for
60565ba42b6SBarry Smith    PDE-constrained optimization.
606a7e14dcfSSatish Balay 
607c3339decSBarry Smith    Logically collective
608a7e14dcfSSatish Balay 
609a7e14dcfSSatish Balay    Input Parameters:
610*47450a7bSBarry Smith +  tao  - the `Tao` context
611*47450a7bSBarry Smith .  J    - Matrix used for the Jacobian
612f4c1ad5cSStefano Zampini .  func - Jacobian evaluation routine
613a7e14dcfSSatish Balay -  ctx  - [optional] user-defined context for private data for the
614*47450a7bSBarry Smith           Jacobian evaluation routine (may be `NULL`)
615a7e14dcfSSatish Balay 
616f4c1ad5cSStefano Zampini    Calling sequence of func:
617f4c1ad5cSStefano Zampini $    func(Tao tao,Vec x,Mat J,void *ctx);
618a7e14dcfSSatish Balay 
619*47450a7bSBarry Smith +  tao - the `Tao` context
620a7e14dcfSSatish Balay .  x   - input vector
621a7e14dcfSSatish Balay .  J   - Jacobian matrix
622a7e14dcfSSatish Balay -  ctx - [optional] user-defined Jacobian context
623a7e14dcfSSatish Balay 
624a7e14dcfSSatish Balay    Level: intermediate
625f4c1ad5cSStefano Zampini 
626*47450a7bSBarry Smith .seealso: [](chapter_tao), `Tao`, `TaoComputeJacobianDesign()`, `TaoSetJacobianStateRoutine()`, `TaoSetStateDesignIS()`
627a7e14dcfSSatish Balay @*/
628d71ae5a4SJacob Faibussowitsch PetscErrorCode TaoSetJacobianDesignRoutine(Tao tao, Mat J, PetscErrorCode (*func)(Tao, Vec, Mat, void *), void *ctx)
629d71ae5a4SJacob Faibussowitsch {
630a7e14dcfSSatish Balay   PetscFunctionBegin;
631441846f8SBarry Smith   PetscValidHeaderSpecific(tao, TAO_CLASSID, 1);
632a7e14dcfSSatish Balay   if (J) {
633a7e14dcfSSatish Balay     PetscValidHeaderSpecific(J, MAT_CLASSID, 2);
634a7e14dcfSSatish Balay     PetscCheckSameComm(tao, 1, J, 2);
635a7e14dcfSSatish Balay   }
636ad540459SPierre Jolivet   if (ctx) tao->user_jac_designP = ctx;
637ad540459SPierre Jolivet   if (func) tao->ops->computejacobiandesign = func;
638a7e14dcfSSatish Balay   if (J) {
6399566063dSJacob Faibussowitsch     PetscCall(PetscObjectReference((PetscObject)J));
6409566063dSJacob Faibussowitsch     PetscCall(MatDestroy(&tao->jacobian_design));
641a7e14dcfSSatish Balay     tao->jacobian_design = J;
642a7e14dcfSSatish Balay   }
6433ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
644a7e14dcfSSatish Balay }
645a7e14dcfSSatish Balay 
646a7e14dcfSSatish Balay /*@
647*47450a7bSBarry Smith    TaoSetStateDesignIS - Indicate to the `Tao` object which variables in the
648a7e14dcfSSatish Balay    solution vector are state variables and which are design.  Only applies to
64965ba42b6SBarry Smith    PDE-constrained optimization.
650a7e14dcfSSatish Balay 
651c3339decSBarry Smith    Logically Collective
652a7e14dcfSSatish Balay 
653a7e14dcfSSatish Balay    Input Parameters:
654*47450a7bSBarry Smith +  tao  - The `Tao` context
655a7e14dcfSSatish Balay .  s_is - the index set corresponding to the state variables
656a7e14dcfSSatish Balay -  d_is - the index set corresponding to the design variables
657a7e14dcfSSatish Balay 
658a7e14dcfSSatish Balay    Level: intermediate
659a7e14dcfSSatish Balay 
660*47450a7bSBarry Smith .seealso: [](chapter_tao), `Tao`, `TaoSetJacobianStateRoutine()`, `TaoSetJacobianDesignRoutine()`
661a7e14dcfSSatish Balay @*/
662d71ae5a4SJacob Faibussowitsch PetscErrorCode TaoSetStateDesignIS(Tao tao, IS s_is, IS d_is)
663d71ae5a4SJacob Faibussowitsch {
66445cf516eSBarry Smith   PetscFunctionBegin;
6659566063dSJacob Faibussowitsch   PetscCall(PetscObjectReference((PetscObject)s_is));
6669566063dSJacob Faibussowitsch   PetscCall(ISDestroy(&tao->state_is));
667a7e14dcfSSatish Balay   tao->state_is = s_is;
6689566063dSJacob Faibussowitsch   PetscCall(PetscObjectReference((PetscObject)(d_is)));
6699566063dSJacob Faibussowitsch   PetscCall(ISDestroy(&tao->design_is));
670a7e14dcfSSatish Balay   tao->design_is = d_is;
6713ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
672a7e14dcfSSatish Balay }
673a7e14dcfSSatish Balay 
674a7e14dcfSSatish Balay /*@C
675a7e14dcfSSatish Balay    TaoComputeJacobianEquality - Computes the Jacobian matrix that has been
67665ba42b6SBarry Smith    set with `TaoSetJacobianEqualityRoutine()`.
677a7e14dcfSSatish Balay 
678c3339decSBarry Smith    Collective
679a7e14dcfSSatish Balay 
680a7e14dcfSSatish Balay    Input Parameters:
681*47450a7bSBarry Smith +  tao - the `Tao` solver context
682f4c1ad5cSStefano Zampini -  X   - input vector
683a7e14dcfSSatish Balay 
684a7e14dcfSSatish Balay    Output Parameters:
685f4c1ad5cSStefano Zampini +  J    - Jacobian matrix
686*47450a7bSBarry Smith -  Jpre - matrix used to construct the preconditioner, often the same as `J`
687*47450a7bSBarry Smith 
688*47450a7bSBarry Smith    Level: developer
689a7e14dcfSSatish Balay 
690a7e14dcfSSatish Balay    Notes:
691a7e14dcfSSatish Balay    Most users should not need to explicitly call this routine, as it
69265ba42b6SBarry Smith    is used internally within the optimization algorithms.
693a7e14dcfSSatish Balay 
694*47450a7bSBarry Smith .seealso: [](chapter_tao), `TaoComputeObjective()`, `TaoComputeObjectiveAndGradient()`, `TaoSetJacobianStateRoutine()`, `TaoComputeJacobianDesign()`, `TaoSetStateDesignIS()`
695a7e14dcfSSatish Balay @*/
696d71ae5a4SJacob Faibussowitsch PetscErrorCode TaoComputeJacobianEquality(Tao tao, Vec X, Mat J, Mat Jpre)
697d71ae5a4SJacob Faibussowitsch {
698a7e14dcfSSatish Balay   PetscFunctionBegin;
699441846f8SBarry Smith   PetscValidHeaderSpecific(tao, TAO_CLASSID, 1);
700a7e14dcfSSatish Balay   PetscValidHeaderSpecific(X, VEC_CLASSID, 2);
701a7e14dcfSSatish Balay   PetscCheckSameComm(tao, 1, X, 2);
702a7e14dcfSSatish Balay   ++tao->njac_equality;
7039566063dSJacob Faibussowitsch   PetscCall(VecLockReadPush(X));
7049566063dSJacob Faibussowitsch   PetscCall(PetscLogEventBegin(TAO_JacobianEval, tao, X, J, Jpre));
705792fecdfSBarry Smith   PetscCallBack("Tao callback Jacobian(equality)", (*tao->ops->computejacobianequality)(tao, X, J, Jpre, tao->user_jac_equalityP));
7069566063dSJacob Faibussowitsch   PetscCall(PetscLogEventEnd(TAO_JacobianEval, tao, X, J, Jpre));
7079566063dSJacob Faibussowitsch   PetscCall(VecLockReadPop(X));
7083ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
709a7e14dcfSSatish Balay }
710a7e14dcfSSatish Balay 
711a7e14dcfSSatish Balay /*@C
712a7e14dcfSSatish Balay    TaoComputeJacobianInequality - Computes the Jacobian matrix that has been
71365ba42b6SBarry Smith    set with `TaoSetJacobianInequalityRoutine()`.
714a7e14dcfSSatish Balay 
715c3339decSBarry Smith    Collective
716a7e14dcfSSatish Balay 
717a7e14dcfSSatish Balay    Input Parameters:
718*47450a7bSBarry Smith +  tao - the `Tao` solver context
719f4c1ad5cSStefano Zampini -  X   - input vector
720a7e14dcfSSatish Balay 
721a7e14dcfSSatish Balay    Output Parameters:
722f4c1ad5cSStefano Zampini +  J    - Jacobian matrix
723*47450a7bSBarry Smith -  Jpre - matrix used to construct the preconditioner
724a7e14dcfSSatish Balay 
725a7e14dcfSSatish Balay    Level: developer
726a7e14dcfSSatish Balay 
727*47450a7bSBarry Smith    Note:
728*47450a7bSBarry Smith    Most users should not need to explicitly call this routine, as it
729*47450a7bSBarry Smith    is used internally within the minimization solvers.
730*47450a7bSBarry Smith 
731*47450a7bSBarry Smith .seealso: [](chapter_tao), `Tao`, `TaoComputeObjective()`, `TaoComputeObjectiveAndGradient()`, `TaoSetJacobianStateRoutine()`, `TaoComputeJacobianDesign()`, `TaoSetStateDesignIS()`
732a7e14dcfSSatish Balay @*/
733d71ae5a4SJacob Faibussowitsch PetscErrorCode TaoComputeJacobianInequality(Tao tao, Vec X, Mat J, Mat Jpre)
734d71ae5a4SJacob Faibussowitsch {
735a7e14dcfSSatish Balay   PetscFunctionBegin;
736441846f8SBarry Smith   PetscValidHeaderSpecific(tao, TAO_CLASSID, 1);
737a7e14dcfSSatish Balay   PetscValidHeaderSpecific(X, VEC_CLASSID, 2);
738a7e14dcfSSatish Balay   PetscCheckSameComm(tao, 1, X, 2);
739a7e14dcfSSatish Balay   ++tao->njac_inequality;
7409566063dSJacob Faibussowitsch   PetscCall(VecLockReadPush(X));
7419566063dSJacob Faibussowitsch   PetscCall(PetscLogEventBegin(TAO_JacobianEval, tao, X, J, Jpre));
742792fecdfSBarry Smith   PetscCallBack("Tao callback Jacobian (inequality)", (*tao->ops->computejacobianinequality)(tao, X, J, Jpre, tao->user_jac_inequalityP));
7439566063dSJacob Faibussowitsch   PetscCall(PetscLogEventEnd(TAO_JacobianEval, tao, X, J, Jpre));
7449566063dSJacob Faibussowitsch   PetscCall(VecLockReadPop(X));
7453ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
746a7e14dcfSSatish Balay }
747a7e14dcfSSatish Balay 
748a7e14dcfSSatish Balay /*@C
749a7e14dcfSSatish Balay    TaoSetJacobianEqualityRoutine - Sets the function to compute the Jacobian
750a7e14dcfSSatish Balay    (and its inverse) of the constraint function with respect to the equality variables.
75165ba42b6SBarry Smith    Used only for PDE-constrained optimization.
752a7e14dcfSSatish Balay 
753c3339decSBarry Smith    Logically collective
754a7e14dcfSSatish Balay 
755a7e14dcfSSatish Balay    Input Parameters:
756*47450a7bSBarry Smith +  tao  - the `Tao` context
757*47450a7bSBarry Smith .  J    - Matrix used for the Jacobian
758*47450a7bSBarry Smith .  Jpre - Matrix that will be used to construct the preconditioner, can be same as `J`.
759f4c1ad5cSStefano Zampini .  func - Jacobian evaluation routine
760a7e14dcfSSatish Balay -  ctx  - [optional] user-defined context for private data for the
761*47450a7bSBarry Smith           Jacobian evaluation routine (may be `NULL`)
762a7e14dcfSSatish Balay 
763f4c1ad5cSStefano Zampini    Calling sequence of func:
764f4c1ad5cSStefano Zampini $    func(Tao tao,Vec x,Mat J,Mat Jpre,void *ctx);
765a7e14dcfSSatish Balay 
766*47450a7bSBarry Smith +  tao  - the `Tao` context
767a7e14dcfSSatish Balay .  x    - input vector
768a7e14dcfSSatish Balay .  J    - Jacobian matrix
769*47450a7bSBarry Smith .  Jpre - matrix used to construct the preconditioner, usually the same as `J`
770a7e14dcfSSatish Balay -  ctx  - [optional] user-defined Jacobian context
771a7e14dcfSSatish Balay 
772a7e14dcfSSatish Balay    Level: intermediate
773f4c1ad5cSStefano Zampini 
774*47450a7bSBarry Smith .seealso: [](chapter_tao), `Tao`, `TaoComputeJacobianEquality()`, `TaoSetJacobianDesignRoutine()`, `TaoSetEqualityDesignIS()`
775a7e14dcfSSatish Balay @*/
776d71ae5a4SJacob Faibussowitsch PetscErrorCode TaoSetJacobianEqualityRoutine(Tao tao, Mat J, Mat Jpre, PetscErrorCode (*func)(Tao, Vec, Mat, Mat, void *), void *ctx)
777d71ae5a4SJacob Faibussowitsch {
778a7e14dcfSSatish Balay   PetscFunctionBegin;
779441846f8SBarry Smith   PetscValidHeaderSpecific(tao, TAO_CLASSID, 1);
780a7e14dcfSSatish Balay   if (J) {
781a7e14dcfSSatish Balay     PetscValidHeaderSpecific(J, MAT_CLASSID, 2);
782a7e14dcfSSatish Balay     PetscCheckSameComm(tao, 1, J, 2);
783a7e14dcfSSatish Balay   }
784a7e14dcfSSatish Balay   if (Jpre) {
785a7e14dcfSSatish Balay     PetscValidHeaderSpecific(Jpre, MAT_CLASSID, 3);
786a7e14dcfSSatish Balay     PetscCheckSameComm(tao, 1, Jpre, 3);
787a7e14dcfSSatish Balay   }
788ad540459SPierre Jolivet   if (ctx) tao->user_jac_equalityP = ctx;
789ad540459SPierre Jolivet   if (func) tao->ops->computejacobianequality = func;
790a7e14dcfSSatish Balay   if (J) {
7919566063dSJacob Faibussowitsch     PetscCall(PetscObjectReference((PetscObject)J));
7929566063dSJacob Faibussowitsch     PetscCall(MatDestroy(&tao->jacobian_equality));
793a7e14dcfSSatish Balay     tao->jacobian_equality = J;
794a7e14dcfSSatish Balay   }
795a7e14dcfSSatish Balay   if (Jpre) {
7969566063dSJacob Faibussowitsch     PetscCall(PetscObjectReference((PetscObject)Jpre));
7979566063dSJacob Faibussowitsch     PetscCall(MatDestroy(&tao->jacobian_equality_pre));
798a7e14dcfSSatish Balay     tao->jacobian_equality_pre = Jpre;
799a7e14dcfSSatish Balay   }
8003ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
801a7e14dcfSSatish Balay }
802a7e14dcfSSatish Balay 
803a7e14dcfSSatish Balay /*@C
804a7e14dcfSSatish Balay    TaoSetJacobianInequalityRoutine - Sets the function to compute the Jacobian
805a7e14dcfSSatish Balay    (and its inverse) of the constraint function with respect to the inequality variables.
80665ba42b6SBarry Smith    Used only for PDE-constrained optimization.
807a7e14dcfSSatish Balay 
808c3339decSBarry Smith    Logically collective
809a7e14dcfSSatish Balay 
810a7e14dcfSSatish Balay    Input Parameters:
811*47450a7bSBarry Smith +  tao  - the `Tao` context
812*47450a7bSBarry Smith .  J    - Matrix used for the Jacobian
813*47450a7bSBarry Smith .  Jpre - Matrix that will be used to construct the preconditioner, can be same as `J`.
814f4c1ad5cSStefano Zampini .  func - Jacobian evaluation routine
815a7e14dcfSSatish Balay -  ctx  - [optional] user-defined context for private data for the
816*47450a7bSBarry Smith           Jacobian evaluation routine (may be `NULL`)
817a7e14dcfSSatish Balay 
818f4c1ad5cSStefano Zampini    Calling sequence of func:
819f4c1ad5cSStefano Zampini $    func(Tao tao,Vec x,Mat J,Mat Jpre,void *ctx);
820a7e14dcfSSatish Balay 
821*47450a7bSBarry Smith +  tao  - the `Tao` context
822a7e14dcfSSatish Balay .  x    - input vector
823a7e14dcfSSatish Balay .  J    - Jacobian matrix
824*47450a7bSBarry Smith .  Jpre - matrix used to construct the preconditioner, usually the same as `J`
825a7e14dcfSSatish Balay -  ctx  - [optional] user-defined Jacobian context
826a7e14dcfSSatish Balay 
827a7e14dcfSSatish Balay    Level: intermediate
828f4c1ad5cSStefano Zampini 
829*47450a7bSBarry Smith .seealso: [](chapter_tao), `Tao`, `TaoComputeJacobianInequality()`, `TaoSetJacobianDesignRoutine()`, `TaoSetInequalityDesignIS()`
830a7e14dcfSSatish Balay @*/
831d71ae5a4SJacob Faibussowitsch PetscErrorCode TaoSetJacobianInequalityRoutine(Tao tao, Mat J, Mat Jpre, PetscErrorCode (*func)(Tao, Vec, Mat, Mat, void *), void *ctx)
832d71ae5a4SJacob Faibussowitsch {
833a7e14dcfSSatish Balay   PetscFunctionBegin;
834441846f8SBarry Smith   PetscValidHeaderSpecific(tao, TAO_CLASSID, 1);
835a7e14dcfSSatish Balay   if (J) {
836a7e14dcfSSatish Balay     PetscValidHeaderSpecific(J, MAT_CLASSID, 2);
837a7e14dcfSSatish Balay     PetscCheckSameComm(tao, 1, J, 2);
838a7e14dcfSSatish Balay   }
839a7e14dcfSSatish Balay   if (Jpre) {
840a7e14dcfSSatish Balay     PetscValidHeaderSpecific(Jpre, MAT_CLASSID, 3);
841a7e14dcfSSatish Balay     PetscCheckSameComm(tao, 1, Jpre, 3);
842a7e14dcfSSatish Balay   }
843ad540459SPierre Jolivet   if (ctx) tao->user_jac_inequalityP = ctx;
844ad540459SPierre Jolivet   if (func) tao->ops->computejacobianinequality = func;
845a7e14dcfSSatish Balay   if (J) {
8469566063dSJacob Faibussowitsch     PetscCall(PetscObjectReference((PetscObject)J));
8479566063dSJacob Faibussowitsch     PetscCall(MatDestroy(&tao->jacobian_inequality));
848a7e14dcfSSatish Balay     tao->jacobian_inequality = J;
849a7e14dcfSSatish Balay   }
850a7e14dcfSSatish Balay   if (Jpre) {
8519566063dSJacob Faibussowitsch     PetscCall(PetscObjectReference((PetscObject)Jpre));
8529566063dSJacob Faibussowitsch     PetscCall(MatDestroy(&tao->jacobian_inequality_pre));
853a7e14dcfSSatish Balay     tao->jacobian_inequality_pre = Jpre;
854a7e14dcfSSatish Balay   }
8553ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
856a7e14dcfSSatish Balay }
857