xref: /petsc/src/tao/interface/taosolver_hj.c (revision db7814771ca77b190574494e87b584e981451db0)
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 
6441846f8SBarry Smith    Logically collective on Tao
7a7e14dcfSSatish Balay 
8a7e14dcfSSatish Balay    Input Parameters:
9441846f8SBarry Smith +  tao  - the Tao context
10a7e14dcfSSatish Balay .  H    - Matrix used for the hessian
11a7e14dcfSSatish Balay .  Hpre - Matrix that will be used operated on by preconditioner, can be same as H
12f4c1ad5cSStefano Zampini .  func - Hessian evaluation routine
13a7e14dcfSSatish Balay -  ctx  - [optional] user-defined context for private data for the
146c23d075SBarry Smith          Hessian evaluation routine (may be NULL)
15a7e14dcfSSatish Balay 
16f4c1ad5cSStefano Zampini    Calling sequence of func:
17f4c1ad5cSStefano Zampini $    func(Tao tao,Vec x,Mat H,Mat Hpre,void *ctx);
18a7e14dcfSSatish Balay 
19441846f8SBarry Smith +  tao  - the Tao  context
20a7e14dcfSSatish Balay .  x    - input vector
21a7e14dcfSSatish Balay .  H    - Hessian matrix
22a7e14dcfSSatish Balay .  Hpre - preconditioner matrix, usually the same as H
23a7e14dcfSSatish Balay -  ctx  - [optional] user-defined Hessian context
24a7e14dcfSSatish Balay 
25a7e14dcfSSatish Balay    Level: beginner
26a82e8c82SStefano Zampini 
27*db781477SPatrick Sanan .seealso: `TaoSetObjective()`, `TaoSetGradient()`, `TaoSetObjectiveAndGradient()`, `TaoGetHessian()`
28a7e14dcfSSatish Balay @*/
29a82e8c82SStefano Zampini PetscErrorCode TaoSetHessian(Tao tao, Mat H, Mat Hpre, PetscErrorCode (*func)(Tao, Vec, Mat, Mat, void*), void *ctx)
30a7e14dcfSSatish Balay {
31a7e14dcfSSatish Balay   PetscFunctionBegin;
32441846f8SBarry Smith   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
33a7e14dcfSSatish Balay   if (H) {
34a7e14dcfSSatish Balay     PetscValidHeaderSpecific(H,MAT_CLASSID,2);
35a7e14dcfSSatish Balay     PetscCheckSameComm(tao,1,H,2);
36a7e14dcfSSatish Balay   }
37a7e14dcfSSatish Balay   if (Hpre) {
38a7e14dcfSSatish Balay     PetscValidHeaderSpecific(Hpre,MAT_CLASSID,3);
39a7e14dcfSSatish Balay     PetscCheckSameComm(tao,1,Hpre,3);
40a7e14dcfSSatish Balay   }
41a82e8c82SStefano Zampini   if (ctx) tao->user_hessP = ctx;
42a82e8c82SStefano Zampini   if (func) tao->ops->computehessian = func;
43a7e14dcfSSatish Balay   if (H) {
449566063dSJacob Faibussowitsch     PetscCall(PetscObjectReference((PetscObject)H));
459566063dSJacob Faibussowitsch     PetscCall(MatDestroy(&tao->hessian));
46a7e14dcfSSatish Balay     tao->hessian = H;
47a7e14dcfSSatish Balay   }
48a7e14dcfSSatish Balay   if (Hpre) {
499566063dSJacob Faibussowitsch     PetscCall(PetscObjectReference((PetscObject)Hpre));
509566063dSJacob Faibussowitsch     PetscCall(MatDestroy(&tao->hessian_pre));
51a7e14dcfSSatish Balay     tao->hessian_pre = Hpre;
52a7e14dcfSSatish Balay   }
53a7e14dcfSSatish Balay   PetscFunctionReturn(0);
54a7e14dcfSSatish Balay }
55a7e14dcfSSatish Balay 
56a82e8c82SStefano Zampini /*@C
57a82e8c82SStefano Zampini    TaoGetHessian - Gets the function to compute the Hessian as well as the location to store the matrix.
58a82e8c82SStefano Zampini 
59a82e8c82SStefano Zampini    Not collective
60a82e8c82SStefano Zampini 
61a82e8c82SStefano Zampini    Input Parameter:
62a82e8c82SStefano Zampini .  tao  - the Tao context
63a82e8c82SStefano Zampini 
64a82e8c82SStefano Zampini    OutputParameters:
65a82e8c82SStefano Zampini +  H    - Matrix used for the hessian
66a82e8c82SStefano Zampini .  Hpre - Matrix that will be used operated on by preconditioner, can be the same as H
67a82e8c82SStefano Zampini .  func - Hessian evaluation routine
68a82e8c82SStefano Zampini -  ctx  - user-defined context for private data for the Hessian evaluation routine
69a82e8c82SStefano Zampini 
70a82e8c82SStefano Zampini    Calling sequence of func:
71a82e8c82SStefano Zampini $    func(Tao tao,Vec x,Mat H,Mat Hpre,void *ctx);
72a82e8c82SStefano Zampini 
73a82e8c82SStefano Zampini +  tao  - the Tao  context
74a82e8c82SStefano Zampini .  x    - input vector
75a82e8c82SStefano Zampini .  H    - Hessian matrix
76a82e8c82SStefano Zampini .  Hpre - preconditioner matrix, usually the same as H
77a82e8c82SStefano Zampini -  ctx  - [optional] user-defined Hessian context
78a82e8c82SStefano Zampini 
79a82e8c82SStefano Zampini    Level: beginner
80a82e8c82SStefano Zampini 
81*db781477SPatrick Sanan .seealso: `TaoGetObjective()`, `TaoGetGradient()`, `TaoGetObjectiveAndGradient()`, `TaoSetHessian()`
82a82e8c82SStefano Zampini @*/
83a82e8c82SStefano Zampini PetscErrorCode TaoGetHessian(Tao tao, Mat *H, Mat *Hpre, PetscErrorCode (**func)(Tao, Vec, Mat, Mat, void*), void **ctx)
84a82e8c82SStefano Zampini {
85a82e8c82SStefano Zampini   PetscFunctionBegin;
86a82e8c82SStefano Zampini   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
87a82e8c82SStefano Zampini   if (H) *H = tao->hessian;
88a82e8c82SStefano Zampini   if (Hpre) *Hpre = tao->hessian_pre;
89a82e8c82SStefano Zampini   if (ctx) *ctx = tao->user_hessP;
90a82e8c82SStefano Zampini   if (func) *func = tao->ops->computehessian;
91a82e8c82SStefano Zampini   PetscFunctionReturn(0);
92a82e8c82SStefano Zampini }
93a82e8c82SStefano Zampini 
9409baa881SHong Zhang PetscErrorCode TaoTestHessian(Tao tao)
9509baa881SHong Zhang {
9609baa881SHong Zhang   Mat               A,B,C,D,hessian;
9709baa881SHong Zhang   Vec               x = tao->solution;
9809baa881SHong Zhang   PetscReal         nrm,gnorm;
9909baa881SHong Zhang   PetscReal         threshold = 1.e-5;
10009baa881SHong Zhang   PetscInt          m,n,M,N;
10109baa881SHong Zhang   PetscBool         complete_print = PETSC_FALSE,test = PETSC_FALSE,flg;
102f49d1c87SHong Zhang   PetscViewer       viewer,mviewer;
10309baa881SHong Zhang   MPI_Comm          comm;
10409baa881SHong Zhang   PetscInt          tabs;
10509baa881SHong Zhang   static PetscBool  directionsprinted = PETSC_FALSE;
106f49d1c87SHong Zhang   PetscViewerFormat format;
10709baa881SHong Zhang 
10809baa881SHong Zhang   PetscFunctionBegin;
109d0609cedSBarry Smith   PetscObjectOptionsBegin((PetscObject)tao);
1109566063dSJacob Faibussowitsch   PetscCall(PetscOptionsName("-tao_test_hessian","Compare hand-coded and finite difference Hessians","None",&test));
1119566063dSJacob Faibussowitsch   PetscCall(PetscOptionsReal("-tao_test_hessian", "Threshold for element difference between hand-coded and finite difference being meaningful","None",threshold,&threshold,NULL));
1129566063dSJacob Faibussowitsch   PetscCall(PetscOptionsViewer("-tao_test_hessian_view","View difference between hand-coded and finite difference Hessians element entries","None",&mviewer,&format,&complete_print));
113d0609cedSBarry Smith   PetscOptionsEnd();
11409baa881SHong Zhang   if (!test) PetscFunctionReturn(0);
11509baa881SHong Zhang 
1169566063dSJacob Faibussowitsch   PetscCall(PetscObjectGetComm((PetscObject)tao,&comm));
1179566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIGetStdout(comm,&viewer));
1189566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIGetTab(viewer, &tabs));
1199566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIISetTab(viewer, ((PetscObject)tao)->tablevel));
1209566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPrintf(viewer,"  ---------- Testing Hessian -------------\n"));
12109baa881SHong Zhang   if (!complete_print && !directionsprinted) {
1229566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer,"  Run with -tao_test_hessian_view and optionally -tao_test_hessian <threshold> to show difference\n"));
1239566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer,"    of hand-coded and finite difference Hessian entries greater than <threshold>.\n"));
12409baa881SHong Zhang   }
12509baa881SHong Zhang   if (!directionsprinted) {
1269566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer,"  Testing hand-coded Hessian, if (for double precision runs) ||J - Jfd||_F/||J||_F is\n"));
1279566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer,"    O(1.e-8), the hand-coded Hessian is probably correct.\n"));
12809baa881SHong Zhang     directionsprinted = PETSC_TRUE;
12909baa881SHong Zhang   }
130f49d1c87SHong Zhang   if (complete_print) {
1319566063dSJacob Faibussowitsch     PetscCall(PetscViewerPushFormat(mviewer,format));
132f49d1c87SHong Zhang   }
13309baa881SHong Zhang 
1349566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)tao->hessian,MATMFFD,&flg));
13509baa881SHong Zhang   if (!flg) hessian = tao->hessian;
13609baa881SHong Zhang   else hessian = tao->hessian_pre;
13709baa881SHong Zhang 
13809baa881SHong Zhang   while (hessian) {
1399566063dSJacob Faibussowitsch     PetscCall(PetscObjectBaseTypeCompareAny((PetscObject)hessian,&flg,MATSEQAIJ,MATMPIAIJ,MATSEQDENSE,MATMPIDENSE,MATSEQBAIJ,MATMPIBAIJ,MATSEQSBAIJ,MATMPIBAIJ,""));
14009baa881SHong Zhang     if (flg) {
14109baa881SHong Zhang       A    = hessian;
1429566063dSJacob Faibussowitsch       PetscCall(PetscObjectReference((PetscObject)A));
14309baa881SHong Zhang     } else {
1449566063dSJacob Faibussowitsch       PetscCall(MatComputeOperator(hessian,MATAIJ,&A));
14509baa881SHong Zhang     }
14609baa881SHong Zhang 
1479566063dSJacob Faibussowitsch     PetscCall(MatCreate(PetscObjectComm((PetscObject)A),&B));
1489566063dSJacob Faibussowitsch     PetscCall(MatGetSize(A,&M,&N));
1499566063dSJacob Faibussowitsch     PetscCall(MatGetLocalSize(A,&m,&n));
1509566063dSJacob Faibussowitsch     PetscCall(MatSetSizes(B,m,n,M,N));
1519566063dSJacob Faibussowitsch     PetscCall(MatSetType(B,((PetscObject)A)->type_name));
1529566063dSJacob Faibussowitsch     PetscCall(MatSetUp(B));
1539566063dSJacob Faibussowitsch     PetscCall(MatSetOption(B,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_FALSE));
15409baa881SHong Zhang 
1559566063dSJacob Faibussowitsch     PetscCall(TaoDefaultComputeHessian(tao,x,B,B,NULL));
15609baa881SHong Zhang 
1579566063dSJacob Faibussowitsch     PetscCall(MatDuplicate(B,MAT_COPY_VALUES,&D));
1589566063dSJacob Faibussowitsch     PetscCall(MatAYPX(D,-1.0,A,DIFFERENT_NONZERO_PATTERN));
1599566063dSJacob Faibussowitsch     PetscCall(MatNorm(D,NORM_FROBENIUS,&nrm));
1609566063dSJacob Faibussowitsch     PetscCall(MatNorm(A,NORM_FROBENIUS,&gnorm));
1619566063dSJacob Faibussowitsch     PetscCall(MatDestroy(&D));
16209baa881SHong Zhang     if (!gnorm) gnorm = 1; /* just in case */
1639566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer,"  ||H - Hfd||_F/||H||_F = %g, ||H - Hfd||_F = %g\n",(double)(nrm/gnorm),(double)nrm));
16409baa881SHong Zhang 
16509baa881SHong Zhang     if (complete_print) {
1669566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer,"  Hand-coded Hessian ----------\n"));
1679566063dSJacob Faibussowitsch       PetscCall(MatView(A,mviewer));
1689566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer,"  Finite difference Hessian ----------\n"));
1699566063dSJacob Faibussowitsch       PetscCall(MatView(B,mviewer));
17009baa881SHong Zhang     }
17109baa881SHong Zhang 
17209baa881SHong Zhang     if (complete_print) {
17309baa881SHong Zhang       PetscInt          Istart, Iend, *ccols, bncols, cncols, j, row;
17409baa881SHong Zhang       PetscScalar       *cvals;
17509baa881SHong Zhang       const PetscInt    *bcols;
17609baa881SHong Zhang       const PetscScalar *bvals;
17709baa881SHong Zhang 
1789566063dSJacob Faibussowitsch       PetscCall(MatAYPX(B,-1.0,A,DIFFERENT_NONZERO_PATTERN));
1799566063dSJacob Faibussowitsch       PetscCall(MatCreate(PetscObjectComm((PetscObject)A),&C));
1809566063dSJacob Faibussowitsch       PetscCall(MatSetSizes(C,m,n,M,N));
1819566063dSJacob Faibussowitsch       PetscCall(MatSetType(C,((PetscObject)A)->type_name));
1829566063dSJacob Faibussowitsch       PetscCall(MatSetUp(C));
1839566063dSJacob Faibussowitsch       PetscCall(MatSetOption(C,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_FALSE));
1849566063dSJacob Faibussowitsch       PetscCall(MatGetOwnershipRange(B,&Istart,&Iend));
18509baa881SHong Zhang 
18609baa881SHong Zhang       for (row = Istart; row < Iend; row++) {
1879566063dSJacob Faibussowitsch         PetscCall(MatGetRow(B,row,&bncols,&bcols,&bvals));
1889566063dSJacob Faibussowitsch         PetscCall(PetscMalloc2(bncols,&ccols,bncols,&cvals));
18909baa881SHong Zhang         for (j = 0, cncols = 0; j < bncols; j++) {
19009baa881SHong Zhang           if (PetscAbsScalar(bvals[j]) > threshold) {
19109baa881SHong Zhang             ccols[cncols] = bcols[j];
19209baa881SHong Zhang             cvals[cncols] = bvals[j];
19309baa881SHong Zhang             cncols += 1;
19409baa881SHong Zhang           }
19509baa881SHong Zhang         }
19609baa881SHong Zhang         if (cncols) {
1979566063dSJacob Faibussowitsch           PetscCall(MatSetValues(C,1,&row,cncols,ccols,cvals,INSERT_VALUES));
19809baa881SHong Zhang         }
1999566063dSJacob Faibussowitsch         PetscCall(MatRestoreRow(B,row,&bncols,&bcols,&bvals));
2009566063dSJacob Faibussowitsch         PetscCall(PetscFree2(ccols,cvals));
20109baa881SHong Zhang       }
2029566063dSJacob Faibussowitsch       PetscCall(MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY));
2039566063dSJacob Faibussowitsch       PetscCall(MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY));
2049566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer,"  Finite-difference minus hand-coded Hessian with tolerance %g ----------\n",(double)threshold));
2059566063dSJacob Faibussowitsch       PetscCall(MatView(C,mviewer));
2069566063dSJacob Faibussowitsch       PetscCall(MatDestroy(&C));
20709baa881SHong Zhang     }
2089566063dSJacob Faibussowitsch     PetscCall(MatDestroy(&A));
2099566063dSJacob Faibussowitsch     PetscCall(MatDestroy(&B));
21009baa881SHong Zhang 
21109baa881SHong Zhang     if (hessian != tao->hessian_pre) {
21209baa881SHong Zhang       hessian = tao->hessian_pre;
2139566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer,"  ---------- Testing Hessian for preconditioner -------------\n"));
21409baa881SHong Zhang     } else hessian = NULL;
21509baa881SHong Zhang   }
216f49d1c87SHong Zhang   if (complete_print) {
2179566063dSJacob Faibussowitsch     PetscCall(PetscViewerPopFormat(mviewer));
2189566063dSJacob Faibussowitsch     PetscCall(PetscViewerDestroy(&mviewer));
219f49d1c87SHong Zhang   }
2209566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIISetTab(viewer,tabs));
22109baa881SHong Zhang   PetscFunctionReturn(0);
22209baa881SHong Zhang }
22309baa881SHong Zhang 
224a7e14dcfSSatish Balay /*@C
225a7e14dcfSSatish Balay    TaoComputeHessian - Computes the Hessian matrix that has been
226a82e8c82SStefano Zampini    set with TaoSetHessian().
227a7e14dcfSSatish Balay 
228441846f8SBarry Smith    Collective on Tao
229a7e14dcfSSatish Balay 
230a7e14dcfSSatish Balay    Input Parameters:
231f4c1ad5cSStefano Zampini +  tao - the Tao solver context
232f4c1ad5cSStefano Zampini -  X   - input vector
233a7e14dcfSSatish Balay 
234a7e14dcfSSatish Balay    Output Parameters:
235a7e14dcfSSatish Balay +  H    - Hessian matrix
236aa6c7ce3SBarry Smith -  Hpre - Preconditioning matrix
237a7e14dcfSSatish Balay 
23809baa881SHong Zhang    Options Database Keys:
23909baa881SHong Zhang +     -tao_test_hessian - compare the user provided Hessian with one compute via finite differences to check for errors
24009baa881SHong 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
241dfe02fe6SHong 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
24209baa881SHong Zhang 
243a7e14dcfSSatish Balay    Notes:
244a7e14dcfSSatish Balay    Most users should not need to explicitly call this routine, as it
245a7e14dcfSSatish Balay    is used internally within the minimization solvers.
246a7e14dcfSSatish Balay 
247a7e14dcfSSatish Balay    TaoComputeHessian() is typically used within minimization
248a7e14dcfSSatish Balay    implementations, so most users would not generally call this routine
249a7e14dcfSSatish Balay    themselves.
250a7e14dcfSSatish Balay 
25109baa881SHong Zhang    Developer Notes:
25209baa881SHong Zhang    The Hessian test mechanism follows SNESTestJacobian().
25309baa881SHong Zhang 
254a7e14dcfSSatish Balay    Level: developer
255a7e14dcfSSatish Balay 
256*db781477SPatrick Sanan .seealso: `TaoComputeObjective()`, `TaoComputeObjectiveAndGradient()`, `TaoSetHessian()`
257a7e14dcfSSatish Balay @*/
258ffad9901SBarry Smith PetscErrorCode TaoComputeHessian(Tao tao, Vec X, Mat H, Mat Hpre)
259a7e14dcfSSatish Balay {
260a7e14dcfSSatish Balay   PetscFunctionBegin;
261441846f8SBarry Smith   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
262a7e14dcfSSatish Balay   PetscValidHeaderSpecific(X, VEC_CLASSID,2);
263a7e14dcfSSatish Balay   PetscCheckSameComm(tao,1,X,2);
2643c859ba3SBarry Smith   PetscCheck(tao->ops->computehessian,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Must call TaoSetHessian() first");
265a7e14dcfSSatish Balay   ++tao->nhess;
2669566063dSJacob Faibussowitsch   PetscCall(VecLockReadPush(X));
2679566063dSJacob Faibussowitsch   PetscCall(PetscLogEventBegin(TAO_HessianEval,tao,X,H,Hpre));
268441846f8SBarry Smith   PetscStackPush("Tao user Hessian function");
2699566063dSJacob Faibussowitsch   PetscCall((*tao->ops->computehessian)(tao,X,H,Hpre,tao->user_hessP));
270a7e14dcfSSatish Balay   PetscStackPop;
2719566063dSJacob Faibussowitsch   PetscCall(PetscLogEventEnd(TAO_HessianEval,tao,X,H,Hpre));
2729566063dSJacob Faibussowitsch   PetscCall(VecLockReadPop(X));
27309baa881SHong Zhang 
2749566063dSJacob Faibussowitsch   PetscCall(TaoTestHessian(tao));
275a7e14dcfSSatish Balay   PetscFunctionReturn(0);
276a7e14dcfSSatish Balay }
277a7e14dcfSSatish Balay 
278a7e14dcfSSatish Balay /*@C
279a7e14dcfSSatish Balay    TaoComputeJacobian - Computes the Jacobian matrix that has been
280a7e14dcfSSatish Balay    set with TaoSetJacobianRoutine().
281a7e14dcfSSatish Balay 
282441846f8SBarry Smith    Collective on Tao
283a7e14dcfSSatish Balay 
284a7e14dcfSSatish Balay    Input Parameters:
285f4c1ad5cSStefano Zampini +  tao - the Tao solver context
286f4c1ad5cSStefano Zampini -  X   - input vector
287a7e14dcfSSatish Balay 
288a7e14dcfSSatish Balay    Output Parameters:
289f4c1ad5cSStefano Zampini +  J    - Jacobian matrix
290f4c1ad5cSStefano Zampini -  Jpre - Preconditioning matrix
291a7e14dcfSSatish Balay 
292a7e14dcfSSatish Balay    Notes:
293a7e14dcfSSatish Balay    Most users should not need to explicitly call this routine, as it
294a7e14dcfSSatish Balay    is used internally within the minimization solvers.
295a7e14dcfSSatish Balay 
296a7e14dcfSSatish Balay    TaoComputeJacobian() is typically used within minimization
297a7e14dcfSSatish Balay    implementations, so most users would not generally call this routine
298a7e14dcfSSatish Balay    themselves.
299a7e14dcfSSatish Balay 
300a7e14dcfSSatish Balay    Level: developer
301a7e14dcfSSatish Balay 
302*db781477SPatrick Sanan .seealso: `TaoComputeObjective()`, `TaoComputeObjectiveAndGradient()`, `TaoSetJacobianRoutine()`
303a7e14dcfSSatish Balay @*/
304ffad9901SBarry Smith PetscErrorCode TaoComputeJacobian(Tao tao, Vec X, Mat J, Mat Jpre)
305a7e14dcfSSatish Balay {
306a7e14dcfSSatish Balay   PetscFunctionBegin;
307441846f8SBarry Smith   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
308a7e14dcfSSatish Balay   PetscValidHeaderSpecific(X, VEC_CLASSID,2);
309a7e14dcfSSatish Balay   PetscCheckSameComm(tao,1,X,2);
3103c859ba3SBarry Smith   PetscCheck(tao->ops->computejacobian,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Must call TaoSetJacobian() first");
311a7e14dcfSSatish Balay   ++tao->njac;
3129566063dSJacob Faibussowitsch   PetscCall(VecLockReadPush(X));
3139566063dSJacob Faibussowitsch   PetscCall(PetscLogEventBegin(TAO_JacobianEval,tao,X,J,Jpre));
314441846f8SBarry Smith   PetscStackPush("Tao user Jacobian function");
3159566063dSJacob Faibussowitsch   PetscCall((*tao->ops->computejacobian)(tao,X,J,Jpre,tao->user_jacP));
316a7e14dcfSSatish Balay   PetscStackPop;
3179566063dSJacob Faibussowitsch   PetscCall(PetscLogEventEnd(TAO_JacobianEval,tao,X,J,Jpre));
3189566063dSJacob Faibussowitsch   PetscCall(VecLockReadPop(X));
319a7e14dcfSSatish Balay   PetscFunctionReturn(0);
320a7e14dcfSSatish Balay }
321a7e14dcfSSatish Balay 
322a7e14dcfSSatish Balay /*@C
3234a48860cSAlp Dener    TaoComputeResidualJacobian - Computes the least-squares residual Jacobian matrix that has been
324a6fed868SAlp Dener    set with TaoSetJacobianResidual().
3254a48860cSAlp Dener 
3264a48860cSAlp Dener    Collective on Tao
3274a48860cSAlp Dener 
3284a48860cSAlp Dener    Input Parameters:
3294a48860cSAlp Dener +  tao - the Tao solver context
3304a48860cSAlp Dener -  X   - input vector
3314a48860cSAlp Dener 
3324a48860cSAlp Dener    Output Parameters:
3334a48860cSAlp Dener +  J    - Jacobian matrix
3344a48860cSAlp Dener -  Jpre - Preconditioning matrix
3354a48860cSAlp Dener 
3364a48860cSAlp Dener    Notes:
3374a48860cSAlp Dener    Most users should not need to explicitly call this routine, as it
3384a48860cSAlp Dener    is used internally within the minimization solvers.
3394a48860cSAlp Dener 
3404a48860cSAlp Dener    TaoComputeResidualJacobian() is typically used within least-squares
3414a48860cSAlp Dener    implementations, so most users would not generally call this routine
3424a48860cSAlp Dener    themselves.
3434a48860cSAlp Dener 
3444a48860cSAlp Dener    Level: developer
3454a48860cSAlp Dener 
346*db781477SPatrick Sanan .seealso: `TaoComputeResidual()`, `TaoSetJacobianResidual()`
3474a48860cSAlp Dener @*/
3484a48860cSAlp Dener PetscErrorCode TaoComputeResidualJacobian(Tao tao, Vec X, Mat J, Mat Jpre)
3494a48860cSAlp Dener {
3504a48860cSAlp Dener   PetscFunctionBegin;
3514a48860cSAlp Dener   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
3524a48860cSAlp Dener   PetscValidHeaderSpecific(X, VEC_CLASSID,2);
3534a48860cSAlp Dener   PetscCheckSameComm(tao,1,X,2);
3543c859ba3SBarry Smith   PetscCheck(tao->ops->computeresidualjacobian,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Must call TaoSetResidualJacobian() first");
3554a48860cSAlp Dener   ++tao->njac;
3569566063dSJacob Faibussowitsch   PetscCall(VecLockReadPush(X));
3579566063dSJacob Faibussowitsch   PetscCall(PetscLogEventBegin(TAO_JacobianEval,tao,X,J,Jpre));
3584a48860cSAlp Dener   PetscStackPush("Tao user least-squares residual Jacobian function");
3599566063dSJacob Faibussowitsch   PetscCall((*tao->ops->computeresidualjacobian)(tao,X,J,Jpre,tao->user_lsjacP));
3604a48860cSAlp Dener   PetscStackPop;
3619566063dSJacob Faibussowitsch   PetscCall(PetscLogEventEnd(TAO_JacobianEval,tao,X,J,Jpre));
3629566063dSJacob Faibussowitsch   PetscCall(VecLockReadPop(X));
3634a48860cSAlp Dener   PetscFunctionReturn(0);
3644a48860cSAlp Dener }
3654a48860cSAlp Dener 
3664a48860cSAlp Dener /*@C
367a7e14dcfSSatish Balay    TaoComputeJacobianState - Computes the Jacobian matrix that has been
368a7e14dcfSSatish Balay    set with TaoSetJacobianStateRoutine().
369a7e14dcfSSatish Balay 
370441846f8SBarry Smith    Collective on Tao
371a7e14dcfSSatish Balay 
372a7e14dcfSSatish Balay    Input Parameters:
373f4c1ad5cSStefano Zampini +  tao - the Tao solver context
374f4c1ad5cSStefano Zampini -  X   - input vector
375a7e14dcfSSatish Balay 
376a7e14dcfSSatish Balay    Output Parameters:
3776b867d5aSJose E. Roman +  J    - Jacobian matrix
3786b867d5aSJose E. Roman .  Jpre - Preconditioning matrix
3796b867d5aSJose E. Roman -  Jinv -
380a7e14dcfSSatish Balay 
381a7e14dcfSSatish Balay    Notes:
382a7e14dcfSSatish Balay    Most users should not need to explicitly call this routine, as it
383a7e14dcfSSatish Balay    is used internally within the minimization solvers.
384a7e14dcfSSatish Balay 
385a7e14dcfSSatish Balay    TaoComputeJacobianState() is typically used within minimization
386a7e14dcfSSatish Balay    implementations, so most users would not generally call this routine
387a7e14dcfSSatish Balay    themselves.
388a7e14dcfSSatish Balay 
389a7e14dcfSSatish Balay    Level: developer
390a7e14dcfSSatish Balay 
391*db781477SPatrick Sanan .seealso: `TaoComputeObjective()`, `TaoComputeObjectiveAndGradient()`, `TaoSetJacobianStateRoutine()`, `TaoComputeJacobianDesign()`, `TaoSetStateDesignIS()`
392a7e14dcfSSatish Balay @*/
393ffad9901SBarry Smith PetscErrorCode TaoComputeJacobianState(Tao tao, Vec X, Mat J, Mat Jpre, Mat Jinv)
394a7e14dcfSSatish Balay {
395a7e14dcfSSatish Balay   PetscFunctionBegin;
396441846f8SBarry Smith   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
397a7e14dcfSSatish Balay   PetscValidHeaderSpecific(X, VEC_CLASSID,2);
398a7e14dcfSSatish Balay   PetscCheckSameComm(tao,1,X,2);
3993c859ba3SBarry Smith   PetscCheck(tao->ops->computejacobianstate,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Must call TaoSetJacobianState() first");
400a7e14dcfSSatish Balay   ++tao->njac_state;
4019566063dSJacob Faibussowitsch   PetscCall(VecLockReadPush(X));
4029566063dSJacob Faibussowitsch   PetscCall(PetscLogEventBegin(TAO_JacobianEval,tao,X,J,Jpre));
403441846f8SBarry Smith   PetscStackPush("Tao user Jacobian(state) function");
4049566063dSJacob Faibussowitsch   PetscCall((*tao->ops->computejacobianstate)(tao,X,J,Jpre,Jinv,tao->user_jac_stateP));
405a7e14dcfSSatish Balay   PetscStackPop;
4069566063dSJacob Faibussowitsch   PetscCall(PetscLogEventEnd(TAO_JacobianEval,tao,X,J,Jpre));
4079566063dSJacob Faibussowitsch   PetscCall(VecLockReadPop(X));
408a7e14dcfSSatish Balay   PetscFunctionReturn(0);
409a7e14dcfSSatish Balay }
410a7e14dcfSSatish Balay 
411a7e14dcfSSatish Balay /*@C
412a7e14dcfSSatish Balay    TaoComputeJacobianDesign - Computes the Jacobian matrix that has been
413a7e14dcfSSatish Balay    set with TaoSetJacobianDesignRoutine().
414a7e14dcfSSatish Balay 
415441846f8SBarry Smith    Collective on Tao
416a7e14dcfSSatish Balay 
417a7e14dcfSSatish Balay    Input Parameters:
418f4c1ad5cSStefano Zampini +  tao - the Tao solver context
419f4c1ad5cSStefano Zampini -  X   - input vector
420a7e14dcfSSatish Balay 
421a7e14dcfSSatish Balay    Output Parameters:
422f4c1ad5cSStefano Zampini .  J - Jacobian matrix
423a7e14dcfSSatish Balay 
424a7e14dcfSSatish Balay    Notes:
425a7e14dcfSSatish Balay    Most users should not need to explicitly call this routine, as it
426a7e14dcfSSatish Balay    is used internally within the minimization solvers.
427a7e14dcfSSatish Balay 
428a7e14dcfSSatish Balay    TaoComputeJacobianDesign() is typically used within minimization
429a7e14dcfSSatish Balay    implementations, so most users would not generally call this routine
430a7e14dcfSSatish Balay    themselves.
431a7e14dcfSSatish Balay 
432a7e14dcfSSatish Balay    Level: developer
433a7e14dcfSSatish Balay 
434*db781477SPatrick Sanan .seealso: `TaoComputeObjective()`, `TaoComputeObjectiveAndGradient()`, `TaoSetJacobianDesignRoutine()`, `TaoComputeJacobianDesign()`, `TaoSetStateDesignIS()`
435a7e14dcfSSatish Balay @*/
43694ab13aaSBarry Smith PetscErrorCode TaoComputeJacobianDesign(Tao tao, Vec X, Mat J)
437a7e14dcfSSatish Balay {
438a7e14dcfSSatish Balay   PetscFunctionBegin;
439441846f8SBarry Smith   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
440a7e14dcfSSatish Balay   PetscValidHeaderSpecific(X, VEC_CLASSID,2);
441a7e14dcfSSatish Balay   PetscCheckSameComm(tao,1,X,2);
4423c859ba3SBarry Smith   PetscCheck(tao->ops->computejacobiandesign,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Must call TaoSetJacobianDesign() first");
443a7e14dcfSSatish Balay   ++tao->njac_design;
4449566063dSJacob Faibussowitsch   PetscCall(VecLockReadPush(X));
4459566063dSJacob Faibussowitsch   PetscCall(PetscLogEventBegin(TAO_JacobianEval,tao,X,J,NULL));
446441846f8SBarry Smith   PetscStackPush("Tao user Jacobian(design) function");
4479566063dSJacob Faibussowitsch   PetscCall((*tao->ops->computejacobiandesign)(tao,X,J,tao->user_jac_designP));
448a7e14dcfSSatish Balay   PetscStackPop;
4499566063dSJacob Faibussowitsch   PetscCall(PetscLogEventEnd(TAO_JacobianEval,tao,X,J,NULL));
4509566063dSJacob Faibussowitsch   PetscCall(VecLockReadPop(X));
451a7e14dcfSSatish Balay   PetscFunctionReturn(0);
452a7e14dcfSSatish Balay }
453a7e14dcfSSatish Balay 
454a7e14dcfSSatish Balay /*@C
455a7e14dcfSSatish Balay    TaoSetJacobianRoutine - Sets the function to compute the Jacobian as well as the location to store the matrix.
456a7e14dcfSSatish Balay 
457441846f8SBarry Smith    Logically collective on Tao
458a7e14dcfSSatish Balay 
459a7e14dcfSSatish Balay    Input Parameters:
460441846f8SBarry Smith +  tao  - the Tao context
461a7e14dcfSSatish Balay .  J    - Matrix used for the jacobian
462a7e14dcfSSatish Balay .  Jpre - Matrix that will be used operated on by preconditioner, can be same as J
463f4c1ad5cSStefano Zampini .  func - Jacobian evaluation routine
464a7e14dcfSSatish Balay -  ctx  - [optional] user-defined context for private data for the
4656c23d075SBarry Smith           Jacobian evaluation routine (may be NULL)
466a7e14dcfSSatish Balay 
467f4c1ad5cSStefano Zampini    Calling sequence of func:
468f4c1ad5cSStefano Zampini $    func(Tao tao,Vec x,Mat J,Mat Jpre,void *ctx);
469a7e14dcfSSatish Balay 
470441846f8SBarry Smith +  tao  - the Tao  context
471a7e14dcfSSatish Balay .  x    - input vector
472a7e14dcfSSatish Balay .  J    - Jacobian matrix
473f4c1ad5cSStefano Zampini .  Jpre - preconditioning matrix, usually the same as J
474a7e14dcfSSatish Balay -  ctx  - [optional] user-defined Jacobian context
475a7e14dcfSSatish Balay 
476a7e14dcfSSatish Balay    Level: intermediate
477a7e14dcfSSatish Balay @*/
478ffad9901SBarry Smith PetscErrorCode TaoSetJacobianRoutine(Tao tao, Mat J, Mat Jpre, PetscErrorCode (*func)(Tao, Vec, Mat, Mat, void*), void *ctx)
479a7e14dcfSSatish Balay {
480a7e14dcfSSatish Balay   PetscFunctionBegin;
481441846f8SBarry Smith   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
482a7e14dcfSSatish Balay   if (J) {
483a7e14dcfSSatish Balay     PetscValidHeaderSpecific(J,MAT_CLASSID,2);
484a7e14dcfSSatish Balay     PetscCheckSameComm(tao,1,J,2);
485a7e14dcfSSatish Balay   }
486a7e14dcfSSatish Balay   if (Jpre) {
487a7e14dcfSSatish Balay     PetscValidHeaderSpecific(Jpre,MAT_CLASSID,3);
488a7e14dcfSSatish Balay     PetscCheckSameComm(tao,1,Jpre,3);
489a7e14dcfSSatish Balay   }
490a7e14dcfSSatish Balay   if (ctx) {
491a7e14dcfSSatish Balay     tao->user_jacP = ctx;
492a7e14dcfSSatish Balay   }
493a7e14dcfSSatish Balay   if (func) {
494a7e14dcfSSatish Balay     tao->ops->computejacobian = func;
495a7e14dcfSSatish Balay   }
496a7e14dcfSSatish Balay   if (J) {
4979566063dSJacob Faibussowitsch     PetscCall(PetscObjectReference((PetscObject)J));
4989566063dSJacob Faibussowitsch     PetscCall(MatDestroy(&tao->jacobian));
499a7e14dcfSSatish Balay     tao->jacobian = J;
500a7e14dcfSSatish Balay   }
501a7e14dcfSSatish Balay   if (Jpre) {
5029566063dSJacob Faibussowitsch     PetscCall(PetscObjectReference((PetscObject)Jpre));
5039566063dSJacob Faibussowitsch     PetscCall(MatDestroy(&tao->jacobian_pre));
504a7e14dcfSSatish Balay     tao->jacobian_pre=Jpre;
505a7e14dcfSSatish Balay   }
506a7e14dcfSSatish Balay   PetscFunctionReturn(0);
507a7e14dcfSSatish Balay }
508a7e14dcfSSatish Balay 
509a7e14dcfSSatish Balay /*@C
5104ffbe8acSAlp Dener    TaoSetJacobianResidualRoutine - Sets the function to compute the least-squares residual Jacobian as well as the
5114a48860cSAlp Dener    location to store the matrix.
5124a48860cSAlp Dener 
5134a48860cSAlp Dener    Logically collective on Tao
5144a48860cSAlp Dener 
5154a48860cSAlp Dener    Input Parameters:
5164a48860cSAlp Dener +  tao  - the Tao context
5174a48860cSAlp Dener .  J    - Matrix used for the jacobian
5184a48860cSAlp Dener .  Jpre - Matrix that will be used operated on by preconditioner, can be same as J
5194a48860cSAlp Dener .  func - Jacobian evaluation routine
5204a48860cSAlp Dener -  ctx  - [optional] user-defined context for private data for the
5214a48860cSAlp Dener           Jacobian evaluation routine (may be NULL)
5224a48860cSAlp Dener 
5234a48860cSAlp Dener    Calling sequence of func:
5244a48860cSAlp Dener $    func(Tao tao,Vec x,Mat J,Mat Jpre,void *ctx);
5254a48860cSAlp Dener 
5264a48860cSAlp Dener +  tao  - the Tao  context
5274a48860cSAlp Dener .  x    - input vector
5284a48860cSAlp Dener .  J    - Jacobian matrix
5294a48860cSAlp Dener .  Jpre - preconditioning matrix, usually the same as J
5304a48860cSAlp Dener -  ctx  - [optional] user-defined Jacobian context
5314a48860cSAlp Dener 
5324a48860cSAlp Dener    Level: intermediate
5334a48860cSAlp Dener @*/
5344ffbe8acSAlp Dener PetscErrorCode TaoSetJacobianResidualRoutine(Tao tao, Mat J, Mat Jpre, PetscErrorCode (*func)(Tao, Vec, Mat, Mat, void*), void *ctx)
5354a48860cSAlp Dener {
5364a48860cSAlp Dener   PetscFunctionBegin;
5374a48860cSAlp Dener   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
5384a48860cSAlp Dener   if (J) {
5394a48860cSAlp Dener     PetscValidHeaderSpecific(J,MAT_CLASSID,2);
5404a48860cSAlp Dener     PetscCheckSameComm(tao,1,J,2);
5414a48860cSAlp Dener   }
5424a48860cSAlp Dener   if (Jpre) {
5434a48860cSAlp Dener     PetscValidHeaderSpecific(Jpre,MAT_CLASSID,3);
5444a48860cSAlp Dener     PetscCheckSameComm(tao,1,Jpre,3);
5454a48860cSAlp Dener   }
5464a48860cSAlp Dener   if (ctx) {
5474a48860cSAlp Dener     tao->user_lsjacP = ctx;
5484a48860cSAlp Dener   }
5494a48860cSAlp Dener   if (func) {
5504a48860cSAlp Dener     tao->ops->computeresidualjacobian = func;
5514a48860cSAlp Dener   }
5524a48860cSAlp Dener   if (J) {
5539566063dSJacob Faibussowitsch     PetscCall(PetscObjectReference((PetscObject)J));
5549566063dSJacob Faibussowitsch     PetscCall(MatDestroy(&tao->ls_jac));
5554a48860cSAlp Dener     tao->ls_jac = J;
5564a48860cSAlp Dener   }
5574a48860cSAlp Dener   if (Jpre) {
5589566063dSJacob Faibussowitsch     PetscCall(PetscObjectReference((PetscObject)Jpre));
5599566063dSJacob Faibussowitsch     PetscCall(MatDestroy(&tao->ls_jac_pre));
5604a48860cSAlp Dener     tao->ls_jac_pre=Jpre;
5614a48860cSAlp Dener   }
5624a48860cSAlp Dener   PetscFunctionReturn(0);
5634a48860cSAlp Dener }
5644a48860cSAlp Dener 
5654a48860cSAlp Dener /*@C
566a7e14dcfSSatish Balay    TaoSetJacobianStateRoutine - Sets the function to compute the Jacobian
567a7e14dcfSSatish Balay    (and its inverse) of the constraint function with respect to the state variables.
568a7e14dcfSSatish Balay    Used only for pde-constrained optimization.
569a7e14dcfSSatish Balay 
570441846f8SBarry Smith    Logically collective on Tao
571a7e14dcfSSatish Balay 
572a7e14dcfSSatish Balay    Input Parameters:
573441846f8SBarry Smith +  tao  - the Tao context
574a7e14dcfSSatish Balay .  J    - Matrix used for the jacobian
5756c23d075SBarry Smith .  Jpre - Matrix that will be used operated on by PETSc preconditioner, can be same as J.  Only used if Jinv is NULL
5766c23d075SBarry 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.
577f4c1ad5cSStefano Zampini .  func - Jacobian evaluation routine
578a7e14dcfSSatish Balay -  ctx  - [optional] user-defined context for private data for the
5796c23d075SBarry Smith           Jacobian evaluation routine (may be NULL)
580a7e14dcfSSatish Balay 
581f4c1ad5cSStefano Zampini    Calling sequence of func:
582f4c1ad5cSStefano Zampini $    func(Tao tao,Vec x,Mat J,Mat Jpre,Mat Jinv,void *ctx);
583a7e14dcfSSatish Balay 
584441846f8SBarry Smith +  tao  - the Tao  context
585a7e14dcfSSatish Balay .  x    - input vector
586a7e14dcfSSatish Balay .  J    - Jacobian matrix
587a7e14dcfSSatish Balay .  Jpre - preconditioner matrix, usually the same as J
588a7e14dcfSSatish Balay .  Jinv - inverse of J
589a7e14dcfSSatish Balay -  ctx  - [optional] user-defined Jacobian context
590a7e14dcfSSatish Balay 
591a7e14dcfSSatish Balay    Level: intermediate
592*db781477SPatrick Sanan .seealso: `TaoComputeJacobianState()`, `TaoSetJacobianDesignRoutine()`, `TaoSetStateDesignIS()`
593a7e14dcfSSatish Balay @*/
594ffad9901SBarry Smith PetscErrorCode TaoSetJacobianStateRoutine(Tao tao, Mat J, Mat Jpre, Mat Jinv, PetscErrorCode (*func)(Tao, Vec, Mat, Mat, Mat, void*), void *ctx)
595a7e14dcfSSatish Balay {
596a7e14dcfSSatish Balay   PetscFunctionBegin;
597441846f8SBarry Smith   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
598a7e14dcfSSatish Balay   if (J) {
599a7e14dcfSSatish Balay     PetscValidHeaderSpecific(J,MAT_CLASSID,2);
600a7e14dcfSSatish Balay     PetscCheckSameComm(tao,1,J,2);
601a7e14dcfSSatish Balay   }
602a7e14dcfSSatish Balay   if (Jpre) {
603a7e14dcfSSatish Balay     PetscValidHeaderSpecific(Jpre,MAT_CLASSID,3);
604a7e14dcfSSatish Balay     PetscCheckSameComm(tao,1,Jpre,3);
605a7e14dcfSSatish Balay   }
606a7e14dcfSSatish Balay   if (Jinv) {
607a7e14dcfSSatish Balay     PetscValidHeaderSpecific(Jinv,MAT_CLASSID,4);
608a7e14dcfSSatish Balay     PetscCheckSameComm(tao,1,Jinv,4);
609a7e14dcfSSatish Balay   }
610a7e14dcfSSatish Balay   if (ctx) {
611a7e14dcfSSatish Balay     tao->user_jac_stateP = ctx;
612a7e14dcfSSatish Balay   }
613a7e14dcfSSatish Balay   if (func) {
614a7e14dcfSSatish Balay     tao->ops->computejacobianstate = func;
615a7e14dcfSSatish Balay   }
616a7e14dcfSSatish Balay   if (J) {
6179566063dSJacob Faibussowitsch     PetscCall(PetscObjectReference((PetscObject)J));
6189566063dSJacob Faibussowitsch     PetscCall(MatDestroy(&tao->jacobian_state));
619a7e14dcfSSatish Balay     tao->jacobian_state = J;
620a7e14dcfSSatish Balay   }
621a7e14dcfSSatish Balay   if (Jpre) {
6229566063dSJacob Faibussowitsch     PetscCall(PetscObjectReference((PetscObject)Jpre));
6239566063dSJacob Faibussowitsch     PetscCall(MatDestroy(&tao->jacobian_state_pre));
624a7e14dcfSSatish Balay     tao->jacobian_state_pre=Jpre;
625a7e14dcfSSatish Balay   }
626a7e14dcfSSatish Balay   if (Jinv) {
6279566063dSJacob Faibussowitsch     PetscCall(PetscObjectReference((PetscObject)Jinv));
6289566063dSJacob Faibussowitsch     PetscCall(MatDestroy(&tao->jacobian_state_inv));
629a7e14dcfSSatish Balay     tao->jacobian_state_inv=Jinv;
630a7e14dcfSSatish Balay   }
631a7e14dcfSSatish Balay   PetscFunctionReturn(0);
632a7e14dcfSSatish Balay }
633a7e14dcfSSatish Balay 
634a7e14dcfSSatish Balay /*@C
635a7e14dcfSSatish Balay    TaoSetJacobianDesignRoutine - Sets the function to compute the Jacobian of
636a7e14dcfSSatish Balay    the constraint function with respect to the design variables.  Used only for
637a7e14dcfSSatish Balay    pde-constrained optimization.
638a7e14dcfSSatish Balay 
639441846f8SBarry Smith    Logically collective on Tao
640a7e14dcfSSatish Balay 
641a7e14dcfSSatish Balay    Input Parameters:
642441846f8SBarry Smith +  tao  - the Tao context
643a7e14dcfSSatish Balay .  J    - Matrix used for the jacobian
644f4c1ad5cSStefano Zampini .  func - Jacobian evaluation routine
645a7e14dcfSSatish Balay -  ctx  - [optional] user-defined context for private data for the
6466c23d075SBarry Smith           Jacobian evaluation routine (may be NULL)
647a7e14dcfSSatish Balay 
648f4c1ad5cSStefano Zampini    Calling sequence of func:
649f4c1ad5cSStefano Zampini $    func(Tao tao,Vec x,Mat J,void *ctx);
650a7e14dcfSSatish Balay 
651441846f8SBarry Smith +  tao - the Tao  context
652a7e14dcfSSatish Balay .  x   - input vector
653a7e14dcfSSatish Balay .  J   - Jacobian matrix
654a7e14dcfSSatish Balay -  ctx - [optional] user-defined Jacobian context
655a7e14dcfSSatish Balay 
656a7e14dcfSSatish Balay    Level: intermediate
657f4c1ad5cSStefano Zampini 
658*db781477SPatrick Sanan .seealso: `TaoComputeJacobianDesign()`, `TaoSetJacobianStateRoutine()`, `TaoSetStateDesignIS()`
659a7e14dcfSSatish Balay @*/
66094ab13aaSBarry Smith PetscErrorCode TaoSetJacobianDesignRoutine(Tao tao, Mat J, PetscErrorCode (*func)(Tao, Vec, Mat, void*), void *ctx)
661a7e14dcfSSatish Balay {
662a7e14dcfSSatish Balay   PetscFunctionBegin;
663441846f8SBarry Smith   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
664a7e14dcfSSatish Balay   if (J) {
665a7e14dcfSSatish Balay     PetscValidHeaderSpecific(J,MAT_CLASSID,2);
666a7e14dcfSSatish Balay     PetscCheckSameComm(tao,1,J,2);
667a7e14dcfSSatish Balay   }
668a7e14dcfSSatish Balay   if (ctx) {
669a7e14dcfSSatish Balay     tao->user_jac_designP = ctx;
670a7e14dcfSSatish Balay   }
671a7e14dcfSSatish Balay   if (func) {
672a7e14dcfSSatish Balay     tao->ops->computejacobiandesign = func;
673a7e14dcfSSatish Balay   }
674a7e14dcfSSatish Balay   if (J) {
6759566063dSJacob Faibussowitsch     PetscCall(PetscObjectReference((PetscObject)J));
6769566063dSJacob Faibussowitsch     PetscCall(MatDestroy(&tao->jacobian_design));
677a7e14dcfSSatish Balay     tao->jacobian_design = J;
678a7e14dcfSSatish Balay   }
679a7e14dcfSSatish Balay   PetscFunctionReturn(0);
680a7e14dcfSSatish Balay }
681a7e14dcfSSatish Balay 
682a7e14dcfSSatish Balay /*@
683441846f8SBarry Smith    TaoSetStateDesignIS - Indicate to the Tao which variables in the
684a7e14dcfSSatish Balay    solution vector are state variables and which are design.  Only applies to
685a7e14dcfSSatish Balay    pde-constrained optimization.
686a7e14dcfSSatish Balay 
687441846f8SBarry Smith    Logically Collective on Tao
688a7e14dcfSSatish Balay 
689a7e14dcfSSatish Balay    Input Parameters:
690441846f8SBarry Smith +  tao  - The Tao context
691a7e14dcfSSatish Balay .  s_is - the index set corresponding to the state variables
692a7e14dcfSSatish Balay -  d_is - the index set corresponding to the design variables
693a7e14dcfSSatish Balay 
694a7e14dcfSSatish Balay    Level: intermediate
695a7e14dcfSSatish Balay 
696*db781477SPatrick Sanan .seealso: `TaoSetJacobianStateRoutine()`, `TaoSetJacobianDesignRoutine()`
697a7e14dcfSSatish Balay @*/
698441846f8SBarry Smith PetscErrorCode TaoSetStateDesignIS(Tao tao, IS s_is, IS d_is)
699a7e14dcfSSatish Balay {
70045cf516eSBarry Smith   PetscFunctionBegin;
7019566063dSJacob Faibussowitsch   PetscCall(PetscObjectReference((PetscObject)s_is));
7029566063dSJacob Faibussowitsch   PetscCall(ISDestroy(&tao->state_is));
703a7e14dcfSSatish Balay   tao->state_is = s_is;
7049566063dSJacob Faibussowitsch   PetscCall(PetscObjectReference((PetscObject)(d_is)));
7059566063dSJacob Faibussowitsch   PetscCall(ISDestroy(&tao->design_is));
706a7e14dcfSSatish Balay   tao->design_is = d_is;
707a7e14dcfSSatish Balay   PetscFunctionReturn(0);
708a7e14dcfSSatish Balay }
709a7e14dcfSSatish Balay 
710a7e14dcfSSatish Balay /*@C
711a7e14dcfSSatish Balay    TaoComputeJacobianEquality - Computes the Jacobian matrix that has been
712a7e14dcfSSatish Balay    set with TaoSetJacobianEqualityRoutine().
713a7e14dcfSSatish Balay 
714441846f8SBarry Smith    Collective on Tao
715a7e14dcfSSatish Balay 
716a7e14dcfSSatish Balay    Input Parameters:
717f4c1ad5cSStefano Zampini +  tao - the Tao solver context
718f4c1ad5cSStefano Zampini -  X   - input vector
719a7e14dcfSSatish Balay 
720a7e14dcfSSatish Balay    Output Parameters:
721f4c1ad5cSStefano Zampini +  J    - Jacobian matrix
722f4c1ad5cSStefano Zampini -  Jpre - Preconditioning matrix
723a7e14dcfSSatish Balay 
724a7e14dcfSSatish Balay    Notes:
725a7e14dcfSSatish Balay    Most users should not need to explicitly call this routine, as it
726a7e14dcfSSatish Balay    is used internally within the minimization solvers.
727a7e14dcfSSatish Balay 
728a7e14dcfSSatish Balay    Level: developer
729a7e14dcfSSatish Balay 
730*db781477SPatrick Sanan .seealso: `TaoComputeObjective()`, `TaoComputeObjectiveAndGradient()`, `TaoSetJacobianStateRoutine()`, `TaoComputeJacobianDesign()`, `TaoSetStateDesignIS()`
731a7e14dcfSSatish Balay @*/
732ffad9901SBarry Smith PetscErrorCode TaoComputeJacobianEquality(Tao tao, Vec X, Mat J, Mat Jpre)
733a7e14dcfSSatish Balay {
734a7e14dcfSSatish Balay   PetscFunctionBegin;
735441846f8SBarry Smith   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
736a7e14dcfSSatish Balay   PetscValidHeaderSpecific(X, VEC_CLASSID,2);
737a7e14dcfSSatish Balay   PetscCheckSameComm(tao,1,X,2);
7383c859ba3SBarry Smith   PetscCheck(tao->ops->computejacobianequality,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Must call TaoSetJacobianEquality() first");
739a7e14dcfSSatish Balay   ++tao->njac_equality;
7409566063dSJacob Faibussowitsch   PetscCall(VecLockReadPush(X));
7419566063dSJacob Faibussowitsch   PetscCall(PetscLogEventBegin(TAO_JacobianEval,tao,X,J,Jpre));
742441846f8SBarry Smith   PetscStackPush("Tao user Jacobian(equality) function");
7439566063dSJacob Faibussowitsch   PetscCall((*tao->ops->computejacobianequality)(tao,X,J,Jpre,tao->user_jac_equalityP));
744a7e14dcfSSatish Balay   PetscStackPop;
7459566063dSJacob Faibussowitsch   PetscCall(PetscLogEventEnd(TAO_JacobianEval,tao,X,J,Jpre));
7469566063dSJacob Faibussowitsch   PetscCall(VecLockReadPop(X));
747a7e14dcfSSatish Balay   PetscFunctionReturn(0);
748a7e14dcfSSatish Balay }
749a7e14dcfSSatish Balay 
750a7e14dcfSSatish Balay /*@C
751a7e14dcfSSatish Balay    TaoComputeJacobianInequality - Computes the Jacobian matrix that has been
752a7e14dcfSSatish Balay    set with TaoSetJacobianInequalityRoutine().
753a7e14dcfSSatish Balay 
754441846f8SBarry Smith    Collective on Tao
755a7e14dcfSSatish Balay 
756a7e14dcfSSatish Balay    Input Parameters:
757f4c1ad5cSStefano Zampini +  tao - the Tao solver context
758f4c1ad5cSStefano Zampini -  X   - input vector
759a7e14dcfSSatish Balay 
760a7e14dcfSSatish Balay    Output Parameters:
761f4c1ad5cSStefano Zampini +  J    - Jacobian matrix
762f4c1ad5cSStefano Zampini -  Jpre - Preconditioning matrix
763a7e14dcfSSatish Balay 
764a7e14dcfSSatish Balay    Notes:
765a7e14dcfSSatish Balay    Most users should not need to explicitly call this routine, as it
766a7e14dcfSSatish Balay    is used internally within the minimization solvers.
767a7e14dcfSSatish Balay 
768a7e14dcfSSatish Balay    Level: developer
769a7e14dcfSSatish Balay 
770*db781477SPatrick Sanan .seealso: `TaoComputeObjective()`, `TaoComputeObjectiveAndGradient()`, `TaoSetJacobianStateRoutine()`, `TaoComputeJacobianDesign()`, `TaoSetStateDesignIS()`
771a7e14dcfSSatish Balay @*/
772ffad9901SBarry Smith PetscErrorCode TaoComputeJacobianInequality(Tao tao, Vec X, Mat J, Mat Jpre)
773a7e14dcfSSatish Balay {
774a7e14dcfSSatish Balay   PetscFunctionBegin;
775441846f8SBarry Smith   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
776a7e14dcfSSatish Balay   PetscValidHeaderSpecific(X, VEC_CLASSID,2);
777a7e14dcfSSatish Balay   PetscCheckSameComm(tao,1,X,2);
7783c859ba3SBarry Smith   PetscCheck(tao->ops->computejacobianinequality,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Must call TaoSetJacobianInequality() first");
779a7e14dcfSSatish Balay   ++tao->njac_inequality;
7809566063dSJacob Faibussowitsch   PetscCall(VecLockReadPush(X));
7819566063dSJacob Faibussowitsch   PetscCall(PetscLogEventBegin(TAO_JacobianEval,tao,X,J,Jpre));
782441846f8SBarry Smith   PetscStackPush("Tao user Jacobian(inequality) function");
7839566063dSJacob Faibussowitsch   PetscCall((*tao->ops->computejacobianinequality)(tao,X,J,Jpre,tao->user_jac_inequalityP));
784a7e14dcfSSatish Balay   PetscStackPop;
7859566063dSJacob Faibussowitsch   PetscCall(PetscLogEventEnd(TAO_JacobianEval,tao,X,J,Jpre));
7869566063dSJacob Faibussowitsch   PetscCall(VecLockReadPop(X));
787a7e14dcfSSatish Balay   PetscFunctionReturn(0);
788a7e14dcfSSatish Balay }
789a7e14dcfSSatish Balay 
790a7e14dcfSSatish Balay /*@C
791a7e14dcfSSatish Balay    TaoSetJacobianEqualityRoutine - Sets the function to compute the Jacobian
792a7e14dcfSSatish Balay    (and its inverse) of the constraint function with respect to the equality variables.
793a7e14dcfSSatish Balay    Used only for pde-constrained optimization.
794a7e14dcfSSatish Balay 
795441846f8SBarry Smith    Logically collective on Tao
796a7e14dcfSSatish Balay 
797a7e14dcfSSatish Balay    Input Parameters:
798441846f8SBarry Smith +  tao  - the Tao context
799a7e14dcfSSatish Balay .  J    - Matrix used for the jacobian
800a7e14dcfSSatish Balay .  Jpre - Matrix that will be used operated on by PETSc preconditioner, can be same as J.
801f4c1ad5cSStefano Zampini .  func - Jacobian evaluation routine
802a7e14dcfSSatish Balay -  ctx  - [optional] user-defined context for private data for the
8036c23d075SBarry Smith           Jacobian evaluation routine (may be NULL)
804a7e14dcfSSatish Balay 
805f4c1ad5cSStefano Zampini    Calling sequence of func:
806f4c1ad5cSStefano Zampini $    func(Tao tao,Vec x,Mat J,Mat Jpre,void *ctx);
807a7e14dcfSSatish Balay 
808441846f8SBarry Smith +  tao  - the Tao  context
809a7e14dcfSSatish Balay .  x    - input vector
810a7e14dcfSSatish Balay .  J    - Jacobian matrix
811a7e14dcfSSatish Balay .  Jpre - preconditioner matrix, usually the same as J
812a7e14dcfSSatish Balay -  ctx  - [optional] user-defined Jacobian context
813a7e14dcfSSatish Balay 
814a7e14dcfSSatish Balay    Level: intermediate
815f4c1ad5cSStefano Zampini 
816*db781477SPatrick Sanan .seealso: `TaoComputeJacobianEquality()`, `TaoSetJacobianDesignRoutine()`, `TaoSetEqualityDesignIS()`
817a7e14dcfSSatish Balay @*/
818ffad9901SBarry Smith PetscErrorCode TaoSetJacobianEqualityRoutine(Tao tao, Mat J, Mat Jpre, PetscErrorCode (*func)(Tao, Vec, Mat, Mat, void*), void *ctx)
819a7e14dcfSSatish Balay {
820a7e14dcfSSatish Balay   PetscFunctionBegin;
821441846f8SBarry Smith   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
822a7e14dcfSSatish Balay   if (J) {
823a7e14dcfSSatish Balay     PetscValidHeaderSpecific(J,MAT_CLASSID,2);
824a7e14dcfSSatish Balay     PetscCheckSameComm(tao,1,J,2);
825a7e14dcfSSatish Balay   }
826a7e14dcfSSatish Balay   if (Jpre) {
827a7e14dcfSSatish Balay     PetscValidHeaderSpecific(Jpre,MAT_CLASSID,3);
828a7e14dcfSSatish Balay     PetscCheckSameComm(tao,1,Jpre,3);
829a7e14dcfSSatish Balay   }
830a7e14dcfSSatish Balay   if (ctx) {
831a7e14dcfSSatish Balay     tao->user_jac_equalityP = ctx;
832a7e14dcfSSatish Balay   }
833a7e14dcfSSatish Balay   if (func) {
834a7e14dcfSSatish Balay     tao->ops->computejacobianequality = func;
835a7e14dcfSSatish Balay   }
836a7e14dcfSSatish Balay   if (J) {
8379566063dSJacob Faibussowitsch     PetscCall(PetscObjectReference((PetscObject)J));
8389566063dSJacob Faibussowitsch     PetscCall(MatDestroy(&tao->jacobian_equality));
839a7e14dcfSSatish Balay     tao->jacobian_equality = J;
840a7e14dcfSSatish Balay   }
841a7e14dcfSSatish Balay   if (Jpre) {
8429566063dSJacob Faibussowitsch     PetscCall(PetscObjectReference((PetscObject)Jpre));
8439566063dSJacob Faibussowitsch     PetscCall(MatDestroy(&tao->jacobian_equality_pre));
844a7e14dcfSSatish Balay     tao->jacobian_equality_pre=Jpre;
845a7e14dcfSSatish Balay   }
846a7e14dcfSSatish Balay   PetscFunctionReturn(0);
847a7e14dcfSSatish Balay }
848a7e14dcfSSatish Balay 
849a7e14dcfSSatish Balay /*@C
850a7e14dcfSSatish Balay    TaoSetJacobianInequalityRoutine - Sets the function to compute the Jacobian
851a7e14dcfSSatish Balay    (and its inverse) of the constraint function with respect to the inequality variables.
852a7e14dcfSSatish Balay    Used only for pde-constrained optimization.
853a7e14dcfSSatish Balay 
854441846f8SBarry Smith    Logically collective on Tao
855a7e14dcfSSatish Balay 
856a7e14dcfSSatish Balay    Input Parameters:
857441846f8SBarry Smith +  tao  - the Tao context
858a7e14dcfSSatish Balay .  J    - Matrix used for the jacobian
859a7e14dcfSSatish Balay .  Jpre - Matrix that will be used operated on by PETSc preconditioner, can be same as J.
860f4c1ad5cSStefano Zampini .  func - Jacobian evaluation routine
861a7e14dcfSSatish Balay -  ctx  - [optional] user-defined context for private data for the
8626c23d075SBarry Smith           Jacobian evaluation routine (may be NULL)
863a7e14dcfSSatish Balay 
864f4c1ad5cSStefano Zampini    Calling sequence of func:
865f4c1ad5cSStefano Zampini $    func(Tao tao,Vec x,Mat J,Mat Jpre,void *ctx);
866a7e14dcfSSatish Balay 
867441846f8SBarry Smith +  tao  - the Tao  context
868a7e14dcfSSatish Balay .  x    - input vector
869a7e14dcfSSatish Balay .  J    - Jacobian matrix
870a7e14dcfSSatish Balay .  Jpre - preconditioner matrix, usually the same as J
871a7e14dcfSSatish Balay -  ctx  - [optional] user-defined Jacobian context
872a7e14dcfSSatish Balay 
873a7e14dcfSSatish Balay    Level: intermediate
874f4c1ad5cSStefano Zampini 
875*db781477SPatrick Sanan .seealso: `TaoComputeJacobianInequality()`, `TaoSetJacobianDesignRoutine()`, `TaoSetInequalityDesignIS()`
876a7e14dcfSSatish Balay @*/
877ffad9901SBarry Smith PetscErrorCode TaoSetJacobianInequalityRoutine(Tao tao, Mat J, Mat Jpre, PetscErrorCode (*func)(Tao, Vec, Mat, Mat,void*), void *ctx)
878a7e14dcfSSatish Balay {
879a7e14dcfSSatish Balay   PetscFunctionBegin;
880441846f8SBarry Smith   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
881a7e14dcfSSatish Balay   if (J) {
882a7e14dcfSSatish Balay     PetscValidHeaderSpecific(J,MAT_CLASSID,2);
883a7e14dcfSSatish Balay     PetscCheckSameComm(tao,1,J,2);
884a7e14dcfSSatish Balay   }
885a7e14dcfSSatish Balay   if (Jpre) {
886a7e14dcfSSatish Balay     PetscValidHeaderSpecific(Jpre,MAT_CLASSID,3);
887a7e14dcfSSatish Balay     PetscCheckSameComm(tao,1,Jpre,3);
888a7e14dcfSSatish Balay   }
889a7e14dcfSSatish Balay   if (ctx) {
890a7e14dcfSSatish Balay     tao->user_jac_inequalityP = ctx;
891a7e14dcfSSatish Balay   }
892a7e14dcfSSatish Balay   if (func) {
893a7e14dcfSSatish Balay     tao->ops->computejacobianinequality = func;
894a7e14dcfSSatish Balay   }
895a7e14dcfSSatish Balay   if (J) {
8969566063dSJacob Faibussowitsch     PetscCall(PetscObjectReference((PetscObject)J));
8979566063dSJacob Faibussowitsch     PetscCall(MatDestroy(&tao->jacobian_inequality));
898a7e14dcfSSatish Balay     tao->jacobian_inequality = J;
899a7e14dcfSSatish Balay   }
900a7e14dcfSSatish Balay   if (Jpre) {
9019566063dSJacob Faibussowitsch     PetscCall(PetscObjectReference((PetscObject)Jpre));
9029566063dSJacob Faibussowitsch     PetscCall(MatDestroy(&tao->jacobian_inequality_pre));
903a7e14dcfSSatish Balay     tao->jacobian_inequality_pre=Jpre;
904a7e14dcfSSatish Balay   }
905a7e14dcfSSatish Balay   PetscFunctionReturn(0);
906a7e14dcfSSatish Balay }
907