xref: /petsc/src/tao/interface/taosolver_hj.c (revision 4ffbe8acf6483a2e43b944c6ff24021ac5e2d5e8)
1af0996ceSBarry Smith #include <petsc/private/taoimpl.h> /*I "petsctao.h" I*/
2a7e14dcfSSatish Balay 
3a7e14dcfSSatish Balay /*@C
4a7e14dcfSSatish Balay    TaoSetHessianRoutine - 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
26a7e14dcfSSatish Balay @*/
27ffad9901SBarry Smith PetscErrorCode TaoSetHessianRoutine(Tao tao, Mat H, Mat Hpre, PetscErrorCode (*func)(Tao, Vec, Mat, Mat, void*), void *ctx)
28a7e14dcfSSatish Balay {
29a7e14dcfSSatish Balay   PetscErrorCode ierr;
3045cf516eSBarry Smith 
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   }
41a7e14dcfSSatish Balay   if (ctx) {
42a7e14dcfSSatish Balay     tao->user_hessP = ctx;
43a7e14dcfSSatish Balay   }
44a7e14dcfSSatish Balay   if (func) {
45a7e14dcfSSatish Balay     tao->ops->computehessian = func;
46a7e14dcfSSatish Balay   }
47a7e14dcfSSatish Balay   if (H) {
48a7e14dcfSSatish Balay     ierr = PetscObjectReference((PetscObject)H);CHKERRQ(ierr);
4945cf516eSBarry Smith     ierr = MatDestroy(&tao->hessian);CHKERRQ(ierr);
50a7e14dcfSSatish Balay     tao->hessian = H;
51a7e14dcfSSatish Balay   }
52a7e14dcfSSatish Balay   if (Hpre) {
53a7e14dcfSSatish Balay     ierr = PetscObjectReference((PetscObject)Hpre);CHKERRQ(ierr);
5445cf516eSBarry Smith     ierr = MatDestroy(&tao->hessian_pre);CHKERRQ(ierr);
55a7e14dcfSSatish Balay     tao->hessian_pre = Hpre;
56a7e14dcfSSatish Balay   }
57a7e14dcfSSatish Balay   PetscFunctionReturn(0);
58a7e14dcfSSatish Balay }
59a7e14dcfSSatish Balay 
6009baa881SHong Zhang PetscErrorCode TaoTestHessian(Tao tao)
6109baa881SHong Zhang {
6209baa881SHong Zhang   Mat               A,B,C,D,hessian;
6309baa881SHong Zhang   Vec               x = tao->solution;
6409baa881SHong Zhang   PetscErrorCode    ierr;
6509baa881SHong Zhang   PetscReal         nrm,gnorm;
6609baa881SHong Zhang   PetscReal         threshold = 1.e-5;
6709baa881SHong Zhang   PetscInt          m,n,M,N;
6809baa881SHong Zhang   PetscBool         complete_print = PETSC_FALSE,test = PETSC_FALSE,flg;
69f49d1c87SHong Zhang   PetscViewer       viewer,mviewer;
7009baa881SHong Zhang   MPI_Comm          comm;
7109baa881SHong Zhang   PetscInt          tabs;
7209baa881SHong Zhang   static PetscBool  directionsprinted = PETSC_FALSE;
73f49d1c87SHong Zhang   PetscViewerFormat format;
7409baa881SHong Zhang 
7509baa881SHong Zhang   PetscFunctionBegin;
7609baa881SHong Zhang   ierr = PetscObjectOptionsBegin((PetscObject)tao);CHKERRQ(ierr);
7709baa881SHong Zhang   ierr = PetscOptionsName("-tao_test_hessian","Compare hand-coded and finite difference Hessians","None",&test);CHKERRQ(ierr);
7809baa881SHong Zhang   ierr = PetscOptionsReal("-tao_test_hessian", "Threshold for element difference between hand-coded and finite difference being meaningful","None",threshold,&threshold,NULL);CHKERRQ(ierr);
79f49d1c87SHong Zhang   ierr = PetscOptionsViewer("-tao_test_hessian_view","View difference between hand-coded and finite difference Hessians element entries","None",&mviewer,&format,&complete_print);CHKERRQ(ierr);
8009baa881SHong Zhang   ierr = PetscOptionsEnd();CHKERRQ(ierr);
8109baa881SHong Zhang   if (!test) PetscFunctionReturn(0);
8209baa881SHong Zhang 
8309baa881SHong Zhang   ierr = PetscObjectGetComm((PetscObject)tao,&comm);CHKERRQ(ierr);
8409baa881SHong Zhang   ierr = PetscViewerASCIIGetStdout(comm,&viewer);CHKERRQ(ierr);
8509baa881SHong Zhang   ierr = PetscViewerASCIIGetTab(viewer, &tabs);CHKERRQ(ierr);
8609baa881SHong Zhang   ierr = PetscViewerASCIISetTab(viewer, ((PetscObject)tao)->tablevel);CHKERRQ(ierr);
8709baa881SHong Zhang   ierr = PetscViewerASCIIPrintf(viewer,"  ---------- Testing Hessian -------------\n");CHKERRQ(ierr);
8809baa881SHong Zhang   if (!complete_print && !directionsprinted) {
8909baa881SHong Zhang     ierr = PetscViewerASCIIPrintf(viewer,"  Run with -tao_test_hessian_view and optionally -tao_test_hessian <threshold> to show difference\n");CHKERRQ(ierr);
9009baa881SHong Zhang     ierr = PetscViewerASCIIPrintf(viewer,"    of hand-coded and finite difference Hessian entries greater than <threshold>.\n");CHKERRQ(ierr);
9109baa881SHong Zhang   }
9209baa881SHong Zhang   if (!directionsprinted) {
9309baa881SHong Zhang     ierr = PetscViewerASCIIPrintf(viewer,"  Testing hand-coded Hessian, if (for double precision runs) ||J - Jfd||_F/||J||_F is\n");CHKERRQ(ierr);
9409baa881SHong Zhang     ierr = PetscViewerASCIIPrintf(viewer,"    O(1.e-8), the hand-coded Hessian is probably correct.\n");CHKERRQ(ierr);
9509baa881SHong Zhang     directionsprinted = PETSC_TRUE;
9609baa881SHong Zhang   }
97f49d1c87SHong Zhang   if (complete_print) {
98f49d1c87SHong Zhang     ierr = PetscViewerPushFormat(mviewer,format);CHKERRQ(ierr);
99f49d1c87SHong Zhang   }
10009baa881SHong Zhang 
10109baa881SHong Zhang   ierr = PetscObjectTypeCompare((PetscObject)tao->hessian,MATMFFD,&flg);CHKERRQ(ierr);
10209baa881SHong Zhang   if (!flg) hessian = tao->hessian;
10309baa881SHong Zhang   else hessian = tao->hessian_pre;
10409baa881SHong Zhang 
10509baa881SHong Zhang   while (hessian) {
10609baa881SHong Zhang     ierr = PetscObjectTypeCompareAny((PetscObject)hessian,&flg,MATSEQAIJ,MATMPIAIJ,MATSEQDENSE,MATMPIDENSE,MATSEQBAIJ,MATMPIBAIJ,MATSEQSBAIJ,MATMPIBAIJ,"");CHKERRQ(ierr);
10709baa881SHong Zhang     if (flg) {
10809baa881SHong Zhang       A    = hessian;
10909baa881SHong Zhang       ierr = PetscObjectReference((PetscObject)A);CHKERRQ(ierr);
11009baa881SHong Zhang     } else {
11109baa881SHong Zhang       ierr = MatComputeExplicitOperator(hessian,&A);CHKERRQ(ierr);
11209baa881SHong Zhang     }
11309baa881SHong Zhang 
11409baa881SHong Zhang     ierr = MatCreate(PetscObjectComm((PetscObject)A),&B);CHKERRQ(ierr);
11509baa881SHong Zhang     ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
11609baa881SHong Zhang     ierr = MatGetLocalSize(A,&m,&n);CHKERRQ(ierr);
11709baa881SHong Zhang     ierr = MatSetSizes(B,m,n,M,N);CHKERRQ(ierr);
11809baa881SHong Zhang     ierr = MatSetType(B,((PetscObject)A)->type_name);CHKERRQ(ierr);
11909baa881SHong Zhang     ierr = MatSetUp(B);CHKERRQ(ierr);
12009baa881SHong Zhang     ierr = MatSetOption(B,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_FALSE);CHKERRQ(ierr);
12109baa881SHong Zhang 
12209baa881SHong Zhang     ierr = TaoDefaultComputeHessian(tao,x,B,B,NULL);CHKERRQ(ierr);
12309baa881SHong Zhang 
12409baa881SHong Zhang     ierr = MatDuplicate(B,MAT_COPY_VALUES,&D);CHKERRQ(ierr);
12509baa881SHong Zhang     ierr = MatAYPX(D,-1.0,A,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr);
12609baa881SHong Zhang     ierr = MatNorm(D,NORM_FROBENIUS,&nrm);CHKERRQ(ierr);
12709baa881SHong Zhang     ierr = MatNorm(A,NORM_FROBENIUS,&gnorm);CHKERRQ(ierr);
12809baa881SHong Zhang     ierr = MatDestroy(&D);CHKERRQ(ierr);
12909baa881SHong Zhang     if (!gnorm) gnorm = 1; /* just in case */
13009baa881SHong Zhang     ierr = PetscViewerASCIIPrintf(viewer,"  ||H - Hfd||_F/||H||_F = %g, ||H - Hfd||_F = %g\n",(double)(nrm/gnorm),(double)nrm);CHKERRQ(ierr);
13109baa881SHong Zhang 
13209baa881SHong Zhang     if (complete_print) {
13309baa881SHong Zhang       ierr = PetscViewerASCIIPrintf(viewer,"  Hand-coded Hessian ----------\n");CHKERRQ(ierr);
134f49d1c87SHong Zhang       ierr = MatView(hessian,mviewer);CHKERRQ(ierr);
13509baa881SHong Zhang       ierr = PetscViewerASCIIPrintf(viewer,"  Finite difference Hessian ----------\n");CHKERRQ(ierr);
136f49d1c87SHong Zhang       ierr = MatView(B,mviewer);CHKERRQ(ierr);
13709baa881SHong Zhang     }
13809baa881SHong Zhang 
13909baa881SHong Zhang     if (complete_print) {
14009baa881SHong Zhang       PetscInt          Istart, Iend, *ccols, bncols, cncols, j, row;
14109baa881SHong Zhang       PetscScalar       *cvals;
14209baa881SHong Zhang       const PetscInt    *bcols;
14309baa881SHong Zhang       const PetscScalar *bvals;
14409baa881SHong Zhang 
14509baa881SHong Zhang       ierr = MatAYPX(B,-1.0,A,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr);
14609baa881SHong Zhang       ierr = MatCreate(PetscObjectComm((PetscObject)A),&C);CHKERRQ(ierr);
14709baa881SHong Zhang       ierr = MatSetSizes(C,m,n,M,N);CHKERRQ(ierr);
14809baa881SHong Zhang       ierr = MatSetType(C,((PetscObject)A)->type_name);CHKERRQ(ierr);
14909baa881SHong Zhang       ierr = MatSetUp(C);CHKERRQ(ierr);
15009baa881SHong Zhang       ierr = MatSetOption(C,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_FALSE);CHKERRQ(ierr);
15109baa881SHong Zhang       ierr = MatGetOwnershipRange(B,&Istart,&Iend);CHKERRQ(ierr);
15209baa881SHong Zhang 
15309baa881SHong Zhang       for (row = Istart; row < Iend; row++) {
15409baa881SHong Zhang         ierr = MatGetRow(B,row,&bncols,&bcols,&bvals);CHKERRQ(ierr);
15509baa881SHong Zhang         ierr = PetscMalloc2(bncols,&ccols,bncols,&cvals);CHKERRQ(ierr);
15609baa881SHong Zhang         for (j = 0, cncols = 0; j < bncols; j++) {
15709baa881SHong Zhang           if (PetscAbsScalar(bvals[j]) > threshold) {
15809baa881SHong Zhang             ccols[cncols] = bcols[j];
15909baa881SHong Zhang             cvals[cncols] = bvals[j];
16009baa881SHong Zhang             cncols += 1;
16109baa881SHong Zhang           }
16209baa881SHong Zhang         }
16309baa881SHong Zhang         if (cncols) {
16409baa881SHong Zhang           ierr = MatSetValues(C,1,&row,cncols,ccols,cvals,INSERT_VALUES);CHKERRQ(ierr);
16509baa881SHong Zhang         }
16609baa881SHong Zhang         ierr = MatRestoreRow(B,row,&bncols,&bcols,&bvals);CHKERRQ(ierr);
16709baa881SHong Zhang         ierr = PetscFree2(ccols,cvals);CHKERRQ(ierr);
16809baa881SHong Zhang       }
16909baa881SHong Zhang       ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
17009baa881SHong Zhang       ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
17109baa881SHong Zhang       ierr = PetscViewerASCIIPrintf(viewer,"  Finite-difference minus hand-coded Hessian with tolerance %g ----------\n",(double)threshold);CHKERRQ(ierr);
172f49d1c87SHong Zhang       ierr = MatView(C,mviewer);CHKERRQ(ierr);
17309baa881SHong Zhang       ierr = MatDestroy(&C);CHKERRQ(ierr);
17409baa881SHong Zhang     }
17509baa881SHong Zhang     ierr = MatDestroy(&A);CHKERRQ(ierr);
17609baa881SHong Zhang     ierr = MatDestroy(&B);CHKERRQ(ierr);
17709baa881SHong Zhang 
17809baa881SHong Zhang     if (hessian != tao->hessian_pre) {
17909baa881SHong Zhang       hessian = tao->hessian_pre;
18009baa881SHong Zhang       ierr = PetscViewerASCIIPrintf(viewer,"  ---------- Testing Hessian for preconditioner -------------\n");CHKERRQ(ierr);
18109baa881SHong Zhang     } else hessian = NULL;
18209baa881SHong Zhang   }
183f49d1c87SHong Zhang   if (complete_print) {
184f49d1c87SHong Zhang     ierr = PetscViewerPopFormat(mviewer);CHKERRQ(ierr);
185f49d1c87SHong Zhang   }
18609baa881SHong Zhang   ierr = PetscViewerASCIISetTab(viewer,tabs);CHKERRQ(ierr);
18709baa881SHong Zhang   PetscFunctionReturn(0);
18809baa881SHong Zhang }
18909baa881SHong Zhang 
190a7e14dcfSSatish Balay /*@C
191a7e14dcfSSatish Balay    TaoComputeHessian - Computes the Hessian matrix that has been
192a7e14dcfSSatish Balay    set with TaoSetHessianRoutine().
193a7e14dcfSSatish Balay 
194441846f8SBarry Smith    Collective on Tao
195a7e14dcfSSatish Balay 
196a7e14dcfSSatish Balay    Input Parameters:
197f4c1ad5cSStefano Zampini +  tao - the Tao solver context
198f4c1ad5cSStefano Zampini -  X   - input vector
199a7e14dcfSSatish Balay 
200a7e14dcfSSatish Balay    Output Parameters:
201a7e14dcfSSatish Balay +  H    - Hessian matrix
202aa6c7ce3SBarry Smith -  Hpre - Preconditioning matrix
203a7e14dcfSSatish Balay 
20409baa881SHong Zhang    Options Database Keys:
20509baa881SHong Zhang +     -tao_test_hessian - compare the user provided Hessian with one compute via finite differences to check for errors
20609baa881SHong 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
207dfe02fe6SHong 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
20809baa881SHong Zhang 
209a7e14dcfSSatish Balay    Notes:
210a7e14dcfSSatish Balay    Most users should not need to explicitly call this routine, as it
211a7e14dcfSSatish Balay    is used internally within the minimization solvers.
212a7e14dcfSSatish Balay 
213a7e14dcfSSatish Balay    TaoComputeHessian() is typically used within minimization
214a7e14dcfSSatish Balay    implementations, so most users would not generally call this routine
215a7e14dcfSSatish Balay    themselves.
216a7e14dcfSSatish Balay 
21709baa881SHong Zhang    Developer Notes:
21809baa881SHong Zhang    The Hessian test mechanism follows SNESTestJacobian().
21909baa881SHong Zhang 
220a7e14dcfSSatish Balay    Level: developer
221a7e14dcfSSatish Balay 
222f4c1ad5cSStefano Zampini .seealso: TaoComputeObjective(), TaoComputeObjectiveAndGradient(), TaoSetHessianRoutine()
223a7e14dcfSSatish Balay @*/
224ffad9901SBarry Smith PetscErrorCode TaoComputeHessian(Tao tao, Vec X, Mat H, Mat Hpre)
225a7e14dcfSSatish Balay {
226a7e14dcfSSatish Balay   PetscErrorCode ierr;
22787f595a5SBarry Smith 
228a7e14dcfSSatish Balay   PetscFunctionBegin;
229441846f8SBarry Smith   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
230a7e14dcfSSatish Balay   PetscValidHeaderSpecific(X, VEC_CLASSID,2);
231a7e14dcfSSatish Balay   PetscCheckSameComm(tao,1,X,2);
232f4c1ad5cSStefano Zampini   if (!tao->ops->computehessian) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Must call TaoSetHessianRoutine() first");
233a7e14dcfSSatish Balay   ++tao->nhess;
234f4c1ad5cSStefano Zampini   ierr = VecLockPush(X);CHKERRQ(ierr);
2350ebee16dSLisandro Dalcin   ierr = PetscLogEventBegin(TAO_HessianEval,tao,X,H,Hpre);CHKERRQ(ierr);
236441846f8SBarry Smith   PetscStackPush("Tao user Hessian function");
237ffad9901SBarry Smith   ierr = (*tao->ops->computehessian)(tao,X,H,Hpre,tao->user_hessP);CHKERRQ(ierr);
238a7e14dcfSSatish Balay   PetscStackPop;
2390ebee16dSLisandro Dalcin   ierr = PetscLogEventEnd(TAO_HessianEval,tao,X,H,Hpre);CHKERRQ(ierr);
240f4c1ad5cSStefano Zampini   ierr = VecLockPop(X);CHKERRQ(ierr);
24109baa881SHong Zhang 
24209baa881SHong Zhang   ierr = TaoTestHessian(tao);CHKERRQ(ierr);
243a7e14dcfSSatish Balay   PetscFunctionReturn(0);
244a7e14dcfSSatish Balay }
245a7e14dcfSSatish Balay 
246a7e14dcfSSatish Balay /*@C
247a7e14dcfSSatish Balay    TaoComputeJacobian - Computes the Jacobian matrix that has been
248a7e14dcfSSatish Balay    set with TaoSetJacobianRoutine().
249a7e14dcfSSatish Balay 
250441846f8SBarry Smith    Collective on Tao
251a7e14dcfSSatish Balay 
252a7e14dcfSSatish Balay    Input Parameters:
253f4c1ad5cSStefano Zampini +  tao - the Tao solver context
254f4c1ad5cSStefano Zampini -  X   - input vector
255a7e14dcfSSatish Balay 
256a7e14dcfSSatish Balay    Output Parameters:
257f4c1ad5cSStefano Zampini +  J    - Jacobian matrix
258f4c1ad5cSStefano Zampini -  Jpre - Preconditioning matrix
259a7e14dcfSSatish Balay 
260a7e14dcfSSatish Balay    Notes:
261a7e14dcfSSatish Balay    Most users should not need to explicitly call this routine, as it
262a7e14dcfSSatish Balay    is used internally within the minimization solvers.
263a7e14dcfSSatish Balay 
264a7e14dcfSSatish Balay    TaoComputeJacobian() is typically used within minimization
265a7e14dcfSSatish Balay    implementations, so most users would not generally call this routine
266a7e14dcfSSatish Balay    themselves.
267a7e14dcfSSatish Balay 
268a7e14dcfSSatish Balay    Level: developer
269a7e14dcfSSatish Balay 
270f4c1ad5cSStefano Zampini .seealso: TaoComputeObjective(), TaoComputeObjectiveAndGradient(), TaoSetJacobianRoutine()
271a7e14dcfSSatish Balay @*/
272ffad9901SBarry Smith PetscErrorCode TaoComputeJacobian(Tao tao, Vec X, Mat J, Mat Jpre)
273a7e14dcfSSatish Balay {
274a7e14dcfSSatish Balay   PetscErrorCode ierr;
27587f595a5SBarry Smith 
276a7e14dcfSSatish Balay   PetscFunctionBegin;
277441846f8SBarry Smith   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
278a7e14dcfSSatish Balay   PetscValidHeaderSpecific(X, VEC_CLASSID,2);
279a7e14dcfSSatish Balay   PetscCheckSameComm(tao,1,X,2);
28087f595a5SBarry Smith   if (!tao->ops->computejacobian) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Must call TaoSetJacobian() first");
281a7e14dcfSSatish Balay   ++tao->njac;
282f4c1ad5cSStefano Zampini   ierr = VecLockPush(X);CHKERRQ(ierr);
2830ebee16dSLisandro Dalcin   ierr = PetscLogEventBegin(TAO_JacobianEval,tao,X,J,Jpre);CHKERRQ(ierr);
284441846f8SBarry Smith   PetscStackPush("Tao user Jacobian function");
285ffad9901SBarry Smith   ierr = (*tao->ops->computejacobian)(tao,X,J,Jpre,tao->user_jacP);CHKERRQ(ierr);
286a7e14dcfSSatish Balay   PetscStackPop;
2870ebee16dSLisandro Dalcin   ierr = PetscLogEventEnd(TAO_JacobianEval,tao,X,J,Jpre);CHKERRQ(ierr);
288f4c1ad5cSStefano Zampini   ierr = VecLockPop(X);CHKERRQ(ierr);
289a7e14dcfSSatish Balay   PetscFunctionReturn(0);
290a7e14dcfSSatish Balay }
291a7e14dcfSSatish Balay 
292a7e14dcfSSatish Balay /*@C
2934a48860cSAlp Dener    TaoComputeResidualJacobian - Computes the least-squares residual Jacobian matrix that has been
2944a48860cSAlp Dener    set with TaoSetResidualJacobianRoutine().
2954a48860cSAlp Dener 
2964a48860cSAlp Dener    Collective on Tao
2974a48860cSAlp Dener 
2984a48860cSAlp Dener    Input Parameters:
2994a48860cSAlp Dener +  tao - the Tao solver context
3004a48860cSAlp Dener -  X   - input vector
3014a48860cSAlp Dener 
3024a48860cSAlp Dener    Output Parameters:
3034a48860cSAlp Dener +  J    - Jacobian matrix
3044a48860cSAlp Dener -  Jpre - Preconditioning matrix
3054a48860cSAlp Dener 
3064a48860cSAlp Dener    Notes:
3074a48860cSAlp Dener    Most users should not need to explicitly call this routine, as it
3084a48860cSAlp Dener    is used internally within the minimization solvers.
3094a48860cSAlp Dener 
3104a48860cSAlp Dener    TaoComputeResidualJacobian() is typically used within least-squares
3114a48860cSAlp Dener    implementations, so most users would not generally call this routine
3124a48860cSAlp Dener    themselves.
3134a48860cSAlp Dener 
3144a48860cSAlp Dener    Level: developer
3154a48860cSAlp Dener 
3164a48860cSAlp Dener .seealso: TaoComputeResidual(), TaoSetResidualJacobianRoutine()
3174a48860cSAlp Dener @*/
3184a48860cSAlp Dener PetscErrorCode TaoComputeResidualJacobian(Tao tao, Vec X, Mat J, Mat Jpre)
3194a48860cSAlp Dener {
3204a48860cSAlp Dener   PetscErrorCode ierr;
3214a48860cSAlp Dener 
3224a48860cSAlp Dener   PetscFunctionBegin;
3234a48860cSAlp Dener   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
3244a48860cSAlp Dener   PetscValidHeaderSpecific(X, VEC_CLASSID,2);
3254a48860cSAlp Dener   PetscCheckSameComm(tao,1,X,2);
3264a48860cSAlp Dener   if (!tao->ops->computeresidualjacobian) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Must call TaoSetResidualJacobian() first");
3274a48860cSAlp Dener   ++tao->njac;
3284a48860cSAlp Dener   ierr = VecLockPush(X);CHKERRQ(ierr);
3294a48860cSAlp Dener   ierr = PetscLogEventBegin(TAO_JacobianEval,tao,X,J,Jpre);CHKERRQ(ierr);
3304a48860cSAlp Dener   PetscStackPush("Tao user least-squares residual Jacobian function");
3314a48860cSAlp Dener   ierr = (*tao->ops->computeresidualjacobian)(tao,X,J,Jpre,tao->user_lsjacP);CHKERRQ(ierr);
3324a48860cSAlp Dener   PetscStackPop;
3334a48860cSAlp Dener   ierr = PetscLogEventEnd(TAO_JacobianEval,tao,X,J,Jpre);CHKERRQ(ierr);
3344a48860cSAlp Dener   ierr = VecLockPop(X);CHKERRQ(ierr);
3354a48860cSAlp Dener   PetscFunctionReturn(0);
3364a48860cSAlp Dener }
3374a48860cSAlp Dener 
3384a48860cSAlp Dener /*@C
339a7e14dcfSSatish Balay    TaoComputeJacobianState - Computes the Jacobian matrix that has been
340a7e14dcfSSatish Balay    set with TaoSetJacobianStateRoutine().
341a7e14dcfSSatish Balay 
342441846f8SBarry Smith    Collective on Tao
343a7e14dcfSSatish Balay 
344a7e14dcfSSatish Balay    Input Parameters:
345f4c1ad5cSStefano Zampini +  tao - the Tao solver context
346f4c1ad5cSStefano Zampini -  X   - input vector
347a7e14dcfSSatish Balay 
348a7e14dcfSSatish Balay    Output Parameters:
349f4c1ad5cSStefano Zampini +  Jpre - Jacobian matrix
350f4c1ad5cSStefano Zampini -  Jinv - Preconditioning matrix
351a7e14dcfSSatish Balay 
352a7e14dcfSSatish Balay    Notes:
353a7e14dcfSSatish Balay    Most users should not need to explicitly call this routine, as it
354a7e14dcfSSatish Balay    is used internally within the minimization solvers.
355a7e14dcfSSatish Balay 
356a7e14dcfSSatish Balay    TaoComputeJacobianState() is typically used within minimization
357a7e14dcfSSatish Balay    implementations, so most users would not generally call this routine
358a7e14dcfSSatish Balay    themselves.
359a7e14dcfSSatish Balay 
360a7e14dcfSSatish Balay    Level: developer
361a7e14dcfSSatish Balay 
362a7e14dcfSSatish Balay .seealso: TaoComputeObjective(), TaoComputeObjectiveAndGradient(), TaoSetJacobianStateRoutine(), TaoComputeJacobianDesign(), TaoSetStateDesignIS()
363a7e14dcfSSatish Balay @*/
364ffad9901SBarry Smith PetscErrorCode TaoComputeJacobianState(Tao tao, Vec X, Mat J, Mat Jpre, Mat Jinv)
365a7e14dcfSSatish Balay {
366a7e14dcfSSatish Balay   PetscErrorCode ierr;
36745cf516eSBarry Smith 
368a7e14dcfSSatish Balay   PetscFunctionBegin;
369441846f8SBarry Smith   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
370a7e14dcfSSatish Balay   PetscValidHeaderSpecific(X, VEC_CLASSID,2);
371a7e14dcfSSatish Balay   PetscCheckSameComm(tao,1,X,2);
37287f595a5SBarry Smith   if (!tao->ops->computejacobianstate) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Must call TaoSetJacobianState() first");
373a7e14dcfSSatish Balay   ++tao->njac_state;
374f4c1ad5cSStefano Zampini   ierr = VecLockPush(X);CHKERRQ(ierr);
3750ebee16dSLisandro Dalcin   ierr = PetscLogEventBegin(TAO_JacobianEval,tao,X,J,Jpre);CHKERRQ(ierr);
376441846f8SBarry Smith   PetscStackPush("Tao user Jacobian(state) function");
377ffad9901SBarry Smith   ierr = (*tao->ops->computejacobianstate)(tao,X,J,Jpre,Jinv,tao->user_jac_stateP);CHKERRQ(ierr);
378a7e14dcfSSatish Balay   PetscStackPop;
3790ebee16dSLisandro Dalcin   ierr = PetscLogEventEnd(TAO_JacobianEval,tao,X,J,Jpre);CHKERRQ(ierr);
380f4c1ad5cSStefano Zampini   ierr = VecLockPop(X);CHKERRQ(ierr);
381a7e14dcfSSatish Balay   PetscFunctionReturn(0);
382a7e14dcfSSatish Balay }
383a7e14dcfSSatish Balay 
384a7e14dcfSSatish Balay /*@C
385a7e14dcfSSatish Balay    TaoComputeJacobianDesign - Computes the Jacobian matrix that has been
386a7e14dcfSSatish Balay    set with TaoSetJacobianDesignRoutine().
387a7e14dcfSSatish Balay 
388441846f8SBarry Smith    Collective on Tao
389a7e14dcfSSatish Balay 
390a7e14dcfSSatish Balay    Input Parameters:
391f4c1ad5cSStefano Zampini +  tao - the Tao solver context
392f4c1ad5cSStefano Zampini -  X   - input vector
393a7e14dcfSSatish Balay 
394a7e14dcfSSatish Balay    Output Parameters:
395f4c1ad5cSStefano Zampini .  J - Jacobian matrix
396a7e14dcfSSatish Balay 
397a7e14dcfSSatish Balay    Notes:
398a7e14dcfSSatish Balay    Most users should not need to explicitly call this routine, as it
399a7e14dcfSSatish Balay    is used internally within the minimization solvers.
400a7e14dcfSSatish Balay 
401a7e14dcfSSatish Balay    TaoComputeJacobianDesign() is typically used within minimization
402a7e14dcfSSatish Balay    implementations, so most users would not generally call this routine
403a7e14dcfSSatish Balay    themselves.
404a7e14dcfSSatish Balay 
405a7e14dcfSSatish Balay    Level: developer
406a7e14dcfSSatish Balay 
407a7e14dcfSSatish Balay .seealso:  TaoComputeObjective(), TaoComputeObjectiveAndGradient(), TaoSetJacobianDesignRoutine(), TaoComputeJacobianDesign(), TaoSetStateDesignIS()
408a7e14dcfSSatish Balay @*/
40994ab13aaSBarry Smith PetscErrorCode TaoComputeJacobianDesign(Tao tao, Vec X, Mat J)
410a7e14dcfSSatish Balay {
411a7e14dcfSSatish Balay   PetscErrorCode ierr;
41287f595a5SBarry Smith 
413a7e14dcfSSatish Balay   PetscFunctionBegin;
414441846f8SBarry Smith   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
415a7e14dcfSSatish Balay   PetscValidHeaderSpecific(X, VEC_CLASSID,2);
416a7e14dcfSSatish Balay   PetscCheckSameComm(tao,1,X,2);
41787f595a5SBarry Smith   if (!tao->ops->computejacobiandesign) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Must call TaoSetJacobianDesign() first");
418a7e14dcfSSatish Balay   ++tao->njac_design;
419f4c1ad5cSStefano Zampini   ierr = VecLockPush(X);CHKERRQ(ierr);
4200ebee16dSLisandro Dalcin   ierr = PetscLogEventBegin(TAO_JacobianEval,tao,X,J,NULL);CHKERRQ(ierr);
421441846f8SBarry Smith   PetscStackPush("Tao user Jacobian(design) function");
422a7e14dcfSSatish Balay   ierr = (*tao->ops->computejacobiandesign)(tao,X,J,tao->user_jac_designP);CHKERRQ(ierr);
423a7e14dcfSSatish Balay   PetscStackPop;
4240ebee16dSLisandro Dalcin   ierr = PetscLogEventEnd(TAO_JacobianEval,tao,X,J,NULL);CHKERRQ(ierr);
425f4c1ad5cSStefano Zampini   ierr = VecLockPop(X);CHKERRQ(ierr);
426a7e14dcfSSatish Balay   PetscFunctionReturn(0);
427a7e14dcfSSatish Balay }
428a7e14dcfSSatish Balay 
429a7e14dcfSSatish Balay /*@C
430a7e14dcfSSatish Balay    TaoSetJacobianRoutine - Sets the function to compute the Jacobian as well as the location to store the matrix.
431a7e14dcfSSatish Balay 
432441846f8SBarry Smith    Logically collective on Tao
433a7e14dcfSSatish Balay 
434a7e14dcfSSatish Balay    Input Parameters:
435441846f8SBarry Smith +  tao  - the Tao context
436a7e14dcfSSatish Balay .  J    - Matrix used for the jacobian
437a7e14dcfSSatish Balay .  Jpre - Matrix that will be used operated on by preconditioner, can be same as J
438f4c1ad5cSStefano Zampini .  func - Jacobian evaluation routine
439a7e14dcfSSatish Balay -  ctx  - [optional] user-defined context for private data for the
4406c23d075SBarry Smith           Jacobian evaluation routine (may be NULL)
441a7e14dcfSSatish Balay 
442f4c1ad5cSStefano Zampini    Calling sequence of func:
443f4c1ad5cSStefano Zampini $    func(Tao tao,Vec x,Mat J,Mat Jpre,void *ctx);
444a7e14dcfSSatish Balay 
445441846f8SBarry Smith +  tao  - the Tao  context
446a7e14dcfSSatish Balay .  x    - input vector
447a7e14dcfSSatish Balay .  J    - Jacobian matrix
448f4c1ad5cSStefano Zampini .  Jpre - preconditioning matrix, usually the same as J
449a7e14dcfSSatish Balay -  ctx  - [optional] user-defined Jacobian context
450a7e14dcfSSatish Balay 
451a7e14dcfSSatish Balay    Level: intermediate
452a7e14dcfSSatish Balay @*/
453ffad9901SBarry Smith PetscErrorCode TaoSetJacobianRoutine(Tao tao, Mat J, Mat Jpre, PetscErrorCode (*func)(Tao, Vec, Mat, Mat, void*), void *ctx)
454a7e14dcfSSatish Balay {
455a7e14dcfSSatish Balay   PetscErrorCode ierr;
456f4c1ad5cSStefano Zampini 
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   }
467a7e14dcfSSatish Balay   if (ctx) {
468a7e14dcfSSatish Balay     tao->user_jacP = ctx;
469a7e14dcfSSatish Balay   }
470a7e14dcfSSatish Balay   if (func) {
471a7e14dcfSSatish Balay     tao->ops->computejacobian = func;
472a7e14dcfSSatish Balay   }
473a7e14dcfSSatish Balay   if (J) {
474a7e14dcfSSatish Balay     ierr = PetscObjectReference((PetscObject)J);CHKERRQ(ierr);
47545cf516eSBarry Smith     ierr = MatDestroy(&tao->jacobian);CHKERRQ(ierr);
476a7e14dcfSSatish Balay     tao->jacobian = J;
477a7e14dcfSSatish Balay   }
478a7e14dcfSSatish Balay   if (Jpre) {
479a7e14dcfSSatish Balay     ierr = PetscObjectReference((PetscObject)Jpre);CHKERRQ(ierr);
48045cf516eSBarry Smith     ierr = MatDestroy(&tao->jacobian_pre);CHKERRQ(ierr);
481a7e14dcfSSatish Balay     tao->jacobian_pre=Jpre;
482a7e14dcfSSatish Balay   }
483a7e14dcfSSatish Balay   PetscFunctionReturn(0);
484a7e14dcfSSatish Balay }
485a7e14dcfSSatish Balay 
486a7e14dcfSSatish Balay /*@C
487*4ffbe8acSAlp Dener    TaoSetJacobianResidualRoutine - Sets the function to compute the least-squares residual Jacobian as well as the
4884a48860cSAlp Dener    location to store the matrix.
4894a48860cSAlp Dener 
4904a48860cSAlp Dener    Logically collective on Tao
4914a48860cSAlp Dener 
4924a48860cSAlp Dener    Input Parameters:
4934a48860cSAlp Dener +  tao  - the Tao context
4944a48860cSAlp Dener .  J    - Matrix used for the jacobian
4954a48860cSAlp Dener .  Jpre - Matrix that will be used operated on by preconditioner, can be same as J
4964a48860cSAlp Dener .  func - Jacobian evaluation routine
4974a48860cSAlp Dener -  ctx  - [optional] user-defined context for private data for the
4984a48860cSAlp Dener           Jacobian evaluation routine (may be NULL)
4994a48860cSAlp Dener 
5004a48860cSAlp Dener    Calling sequence of func:
5014a48860cSAlp Dener $    func(Tao tao,Vec x,Mat J,Mat Jpre,void *ctx);
5024a48860cSAlp Dener 
5034a48860cSAlp Dener +  tao  - the Tao  context
5044a48860cSAlp Dener .  x    - input vector
5054a48860cSAlp Dener .  J    - Jacobian matrix
5064a48860cSAlp Dener .  Jpre - preconditioning matrix, usually the same as J
5074a48860cSAlp Dener -  ctx  - [optional] user-defined Jacobian context
5084a48860cSAlp Dener 
5094a48860cSAlp Dener    Level: intermediate
5104a48860cSAlp Dener @*/
511*4ffbe8acSAlp Dener PetscErrorCode TaoSetJacobianResidualRoutine(Tao tao, Mat J, Mat Jpre, PetscErrorCode (*func)(Tao, Vec, Mat, Mat, void*), void *ctx)
5124a48860cSAlp Dener {
5134a48860cSAlp Dener   PetscErrorCode ierr;
5144a48860cSAlp Dener 
5154a48860cSAlp Dener   PetscFunctionBegin;
5164a48860cSAlp Dener   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
5174a48860cSAlp Dener   if (J) {
5184a48860cSAlp Dener     PetscValidHeaderSpecific(J,MAT_CLASSID,2);
5194a48860cSAlp Dener     PetscCheckSameComm(tao,1,J,2);
5204a48860cSAlp Dener   }
5214a48860cSAlp Dener   if (Jpre) {
5224a48860cSAlp Dener     PetscValidHeaderSpecific(Jpre,MAT_CLASSID,3);
5234a48860cSAlp Dener     PetscCheckSameComm(tao,1,Jpre,3);
5244a48860cSAlp Dener   }
5254a48860cSAlp Dener   if (ctx) {
5264a48860cSAlp Dener     tao->user_lsjacP = ctx;
5274a48860cSAlp Dener   }
5284a48860cSAlp Dener   if (func) {
5294a48860cSAlp Dener     tao->ops->computeresidualjacobian = func;
5304a48860cSAlp Dener   }
5314a48860cSAlp Dener   if (J) {
5324a48860cSAlp Dener     ierr = PetscObjectReference((PetscObject)J);CHKERRQ(ierr);
5334a48860cSAlp Dener     ierr = MatDestroy(&tao->ls_jac);CHKERRQ(ierr);
5344a48860cSAlp Dener     tao->ls_jac = J;
5354a48860cSAlp Dener   }
5364a48860cSAlp Dener   if (Jpre) {
5374a48860cSAlp Dener     ierr = PetscObjectReference((PetscObject)Jpre);CHKERRQ(ierr);
5384a48860cSAlp Dener     ierr = MatDestroy(&tao->ls_jac_pre);CHKERRQ(ierr);
5394a48860cSAlp Dener     tao->ls_jac_pre=Jpre;
5404a48860cSAlp Dener   }
5414a48860cSAlp Dener   PetscFunctionReturn(0);
5424a48860cSAlp Dener }
5434a48860cSAlp Dener 
5444a48860cSAlp Dener /*@C
545a7e14dcfSSatish Balay    TaoSetJacobianStateRoutine - Sets the function to compute the Jacobian
546a7e14dcfSSatish Balay    (and its inverse) of the constraint function with respect to the state variables.
547a7e14dcfSSatish Balay    Used only for pde-constrained optimization.
548a7e14dcfSSatish Balay 
549441846f8SBarry Smith    Logically collective on Tao
550a7e14dcfSSatish Balay 
551a7e14dcfSSatish Balay    Input Parameters:
552441846f8SBarry Smith +  tao  - the Tao context
553a7e14dcfSSatish Balay .  J    - Matrix used for the jacobian
5546c23d075SBarry Smith .  Jpre - Matrix that will be used operated on by PETSc preconditioner, can be same as J.  Only used if Jinv is NULL
5556c23d075SBarry 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.
556f4c1ad5cSStefano Zampini .  func - Jacobian evaluation routine
557a7e14dcfSSatish Balay -  ctx  - [optional] user-defined context for private data for the
5586c23d075SBarry Smith           Jacobian evaluation routine (may be NULL)
559a7e14dcfSSatish Balay 
560f4c1ad5cSStefano Zampini    Calling sequence of func:
561f4c1ad5cSStefano Zampini $    func(Tao tao,Vec x,Mat J,Mat Jpre,Mat Jinv,void *ctx);
562a7e14dcfSSatish Balay 
563441846f8SBarry Smith +  tao  - the Tao  context
564a7e14dcfSSatish Balay .  x    - input vector
565a7e14dcfSSatish Balay .  J    - Jacobian matrix
566a7e14dcfSSatish Balay .  Jpre - preconditioner matrix, usually the same as J
567a7e14dcfSSatish Balay .  Jinv - inverse of J
568a7e14dcfSSatish Balay -  ctx  - [optional] user-defined Jacobian context
569a7e14dcfSSatish Balay 
570a7e14dcfSSatish Balay    Level: intermediate
571f4c1ad5cSStefano Zampini .seealso: TaoComputeJacobianState(), TaoSetJacobianDesignRoutine(), TaoSetStateDesignIS()
572a7e14dcfSSatish Balay @*/
573ffad9901SBarry Smith PetscErrorCode TaoSetJacobianStateRoutine(Tao tao, Mat J, Mat Jpre, Mat Jinv, PetscErrorCode (*func)(Tao, Vec, Mat, Mat, Mat, void*), void *ctx)
574a7e14dcfSSatish Balay {
575a7e14dcfSSatish Balay   PetscErrorCode ierr;
576f4c1ad5cSStefano Zampini 
577a7e14dcfSSatish Balay   PetscFunctionBegin;
578441846f8SBarry Smith   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
579a7e14dcfSSatish Balay   if (J) {
580a7e14dcfSSatish Balay     PetscValidHeaderSpecific(J,MAT_CLASSID,2);
581a7e14dcfSSatish Balay     PetscCheckSameComm(tao,1,J,2);
582a7e14dcfSSatish Balay   }
583a7e14dcfSSatish Balay   if (Jpre) {
584a7e14dcfSSatish Balay     PetscValidHeaderSpecific(Jpre,MAT_CLASSID,3);
585a7e14dcfSSatish Balay     PetscCheckSameComm(tao,1,Jpre,3);
586a7e14dcfSSatish Balay   }
587a7e14dcfSSatish Balay   if (Jinv) {
588a7e14dcfSSatish Balay     PetscValidHeaderSpecific(Jinv,MAT_CLASSID,4);
589a7e14dcfSSatish Balay     PetscCheckSameComm(tao,1,Jinv,4);
590a7e14dcfSSatish Balay   }
591a7e14dcfSSatish Balay   if (ctx) {
592a7e14dcfSSatish Balay     tao->user_jac_stateP = ctx;
593a7e14dcfSSatish Balay   }
594a7e14dcfSSatish Balay   if (func) {
595a7e14dcfSSatish Balay     tao->ops->computejacobianstate = func;
596a7e14dcfSSatish Balay   }
597a7e14dcfSSatish Balay   if (J) {
598a7e14dcfSSatish Balay     ierr = PetscObjectReference((PetscObject)J);CHKERRQ(ierr);
59945cf516eSBarry Smith     ierr = MatDestroy(&tao->jacobian_state);CHKERRQ(ierr);
600a7e14dcfSSatish Balay     tao->jacobian_state = J;
601a7e14dcfSSatish Balay   }
602a7e14dcfSSatish Balay   if (Jpre) {
603a7e14dcfSSatish Balay     ierr = PetscObjectReference((PetscObject)Jpre);CHKERRQ(ierr);
60445cf516eSBarry Smith     ierr = MatDestroy(&tao->jacobian_state_pre);CHKERRQ(ierr);
605a7e14dcfSSatish Balay     tao->jacobian_state_pre=Jpre;
606a7e14dcfSSatish Balay   }
607a7e14dcfSSatish Balay   if (Jinv) {
608a7e14dcfSSatish Balay     ierr = PetscObjectReference((PetscObject)Jinv);CHKERRQ(ierr);
60945cf516eSBarry Smith     ierr = MatDestroy(&tao->jacobian_state_inv);CHKERRQ(ierr);
610a7e14dcfSSatish Balay     tao->jacobian_state_inv=Jinv;
611a7e14dcfSSatish Balay   }
612a7e14dcfSSatish Balay   PetscFunctionReturn(0);
613a7e14dcfSSatish Balay }
614a7e14dcfSSatish Balay 
615a7e14dcfSSatish Balay /*@C
616a7e14dcfSSatish Balay    TaoSetJacobianDesignRoutine - Sets the function to compute the Jacobian of
617a7e14dcfSSatish Balay    the constraint function with respect to the design variables.  Used only for
618a7e14dcfSSatish Balay    pde-constrained optimization.
619a7e14dcfSSatish Balay 
620441846f8SBarry Smith    Logically collective on Tao
621a7e14dcfSSatish Balay 
622a7e14dcfSSatish Balay    Input Parameters:
623441846f8SBarry Smith +  tao  - the Tao context
624a7e14dcfSSatish Balay .  J    - Matrix used for the jacobian
625f4c1ad5cSStefano Zampini .  func - Jacobian evaluation routine
626a7e14dcfSSatish Balay -  ctx  - [optional] user-defined context for private data for the
6276c23d075SBarry Smith           Jacobian evaluation routine (may be NULL)
628a7e14dcfSSatish Balay 
629f4c1ad5cSStefano Zampini    Calling sequence of func:
630f4c1ad5cSStefano Zampini $    func(Tao tao,Vec x,Mat J,void *ctx);
631a7e14dcfSSatish Balay 
632441846f8SBarry Smith +  tao - the Tao  context
633a7e14dcfSSatish Balay .  x   - input vector
634a7e14dcfSSatish Balay .  J   - Jacobian matrix
635a7e14dcfSSatish Balay -  ctx - [optional] user-defined Jacobian context
636a7e14dcfSSatish Balay 
637a7e14dcfSSatish Balay    Level: intermediate
638f4c1ad5cSStefano Zampini 
639a7e14dcfSSatish Balay .seealso: TaoComputeJacobianDesign(), TaoSetJacobianStateRoutine(), TaoSetStateDesignIS()
640a7e14dcfSSatish Balay @*/
64194ab13aaSBarry Smith PetscErrorCode TaoSetJacobianDesignRoutine(Tao tao, Mat J, PetscErrorCode (*func)(Tao, Vec, Mat, void*), void *ctx)
642a7e14dcfSSatish Balay {
643a7e14dcfSSatish Balay   PetscErrorCode ierr;
64445cf516eSBarry Smith 
645a7e14dcfSSatish Balay   PetscFunctionBegin;
646441846f8SBarry Smith   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
647a7e14dcfSSatish Balay   if (J) {
648a7e14dcfSSatish Balay     PetscValidHeaderSpecific(J,MAT_CLASSID,2);
649a7e14dcfSSatish Balay     PetscCheckSameComm(tao,1,J,2);
650a7e14dcfSSatish Balay   }
651a7e14dcfSSatish Balay   if (ctx) {
652a7e14dcfSSatish Balay     tao->user_jac_designP = ctx;
653a7e14dcfSSatish Balay   }
654a7e14dcfSSatish Balay   if (func) {
655a7e14dcfSSatish Balay     tao->ops->computejacobiandesign = func;
656a7e14dcfSSatish Balay   }
657a7e14dcfSSatish Balay   if (J) {
658a7e14dcfSSatish Balay     ierr = PetscObjectReference((PetscObject)J);CHKERRQ(ierr);
65945cf516eSBarry Smith     ierr = MatDestroy(&tao->jacobian_design);CHKERRQ(ierr);
660a7e14dcfSSatish Balay     tao->jacobian_design = J;
661a7e14dcfSSatish Balay   }
662a7e14dcfSSatish Balay   PetscFunctionReturn(0);
663a7e14dcfSSatish Balay }
664a7e14dcfSSatish Balay 
665a7e14dcfSSatish Balay /*@
666441846f8SBarry Smith    TaoSetStateDesignIS - Indicate to the Tao which variables in the
667a7e14dcfSSatish Balay    solution vector are state variables and which are design.  Only applies to
668a7e14dcfSSatish Balay    pde-constrained optimization.
669a7e14dcfSSatish Balay 
670441846f8SBarry Smith    Logically Collective on Tao
671a7e14dcfSSatish Balay 
672a7e14dcfSSatish Balay    Input Parameters:
673441846f8SBarry Smith +  tao  - The Tao context
674a7e14dcfSSatish Balay .  s_is - the index set corresponding to the state variables
675a7e14dcfSSatish Balay -  d_is - the index set corresponding to the design variables
676a7e14dcfSSatish Balay 
677a7e14dcfSSatish Balay    Level: intermediate
678a7e14dcfSSatish Balay 
679a7e14dcfSSatish Balay .seealso: TaoSetJacobianStateRoutine(), TaoSetJacobianDesignRoutine()
680a7e14dcfSSatish Balay @*/
681441846f8SBarry Smith PetscErrorCode TaoSetStateDesignIS(Tao tao, IS s_is, IS d_is)
682a7e14dcfSSatish Balay {
683a7e14dcfSSatish Balay   PetscErrorCode ierr;
68445cf516eSBarry Smith 
68545cf516eSBarry Smith   PetscFunctionBegin;
68645cf516eSBarry Smith   ierr = PetscObjectReference((PetscObject)s_is);CHKERRQ(ierr);
68745cf516eSBarry Smith   ierr = ISDestroy(&tao->state_is);CHKERRQ(ierr);
688a7e14dcfSSatish Balay   tao->state_is = s_is;
68945cf516eSBarry Smith   ierr = PetscObjectReference((PetscObject)(d_is));CHKERRQ(ierr);
69045cf516eSBarry Smith   ierr = ISDestroy(&tao->design_is);CHKERRQ(ierr);
691a7e14dcfSSatish Balay   tao->design_is = d_is;
692a7e14dcfSSatish Balay   PetscFunctionReturn(0);
693a7e14dcfSSatish Balay }
694a7e14dcfSSatish Balay 
695a7e14dcfSSatish Balay /*@C
696a7e14dcfSSatish Balay    TaoComputeJacobianEquality - Computes the Jacobian matrix that has been
697a7e14dcfSSatish Balay    set with TaoSetJacobianEqualityRoutine().
698a7e14dcfSSatish Balay 
699441846f8SBarry Smith    Collective on Tao
700a7e14dcfSSatish Balay 
701a7e14dcfSSatish Balay    Input Parameters:
702f4c1ad5cSStefano Zampini +  tao - the Tao solver context
703f4c1ad5cSStefano Zampini -  X   - input vector
704a7e14dcfSSatish Balay 
705a7e14dcfSSatish Balay    Output Parameters:
706f4c1ad5cSStefano Zampini +  J    - Jacobian matrix
707f4c1ad5cSStefano Zampini -  Jpre - Preconditioning matrix
708a7e14dcfSSatish Balay 
709a7e14dcfSSatish Balay    Notes:
710a7e14dcfSSatish Balay    Most users should not need to explicitly call this routine, as it
711a7e14dcfSSatish Balay    is used internally within the minimization solvers.
712a7e14dcfSSatish Balay 
713a7e14dcfSSatish Balay    Level: developer
714a7e14dcfSSatish Balay 
715a7e14dcfSSatish Balay .seealso:  TaoComputeObjective(), TaoComputeObjectiveAndGradient(), TaoSetJacobianStateRoutine(), TaoComputeJacobianDesign(), TaoSetStateDesignIS()
716a7e14dcfSSatish Balay @*/
717ffad9901SBarry Smith PetscErrorCode TaoComputeJacobianEquality(Tao tao, Vec X, Mat J, Mat Jpre)
718a7e14dcfSSatish Balay {
719a7e14dcfSSatish Balay   PetscErrorCode ierr;
72045cf516eSBarry Smith 
721a7e14dcfSSatish Balay   PetscFunctionBegin;
722441846f8SBarry Smith   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
723a7e14dcfSSatish Balay   PetscValidHeaderSpecific(X, VEC_CLASSID,2);
724a7e14dcfSSatish Balay   PetscCheckSameComm(tao,1,X,2);
72587f595a5SBarry Smith   if (!tao->ops->computejacobianequality) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Must call TaoSetJacobianEquality() first");
726a7e14dcfSSatish Balay   ++tao->njac_equality;
727f4c1ad5cSStefano Zampini   ierr = VecLockPush(X);CHKERRQ(ierr);
7280ebee16dSLisandro Dalcin   ierr = PetscLogEventBegin(TAO_JacobianEval,tao,X,J,Jpre);CHKERRQ(ierr);
729441846f8SBarry Smith   PetscStackPush("Tao user Jacobian(equality) function");
730ffad9901SBarry Smith   ierr = (*tao->ops->computejacobianequality)(tao,X,J,Jpre,tao->user_jac_equalityP);CHKERRQ(ierr);
731a7e14dcfSSatish Balay   PetscStackPop;
7320ebee16dSLisandro Dalcin   ierr = PetscLogEventEnd(TAO_JacobianEval,tao,X,J,Jpre);CHKERRQ(ierr);
733f4c1ad5cSStefano Zampini   ierr = VecLockPop(X);CHKERRQ(ierr);
734a7e14dcfSSatish Balay   PetscFunctionReturn(0);
735a7e14dcfSSatish Balay }
736a7e14dcfSSatish Balay 
737a7e14dcfSSatish Balay /*@C
738a7e14dcfSSatish Balay    TaoComputeJacobianInequality - Computes the Jacobian matrix that has been
739a7e14dcfSSatish Balay    set with TaoSetJacobianInequalityRoutine().
740a7e14dcfSSatish Balay 
741441846f8SBarry Smith    Collective on Tao
742a7e14dcfSSatish Balay 
743a7e14dcfSSatish Balay    Input Parameters:
744f4c1ad5cSStefano Zampini +  tao - the Tao solver context
745f4c1ad5cSStefano Zampini -  X   - input vector
746a7e14dcfSSatish Balay 
747a7e14dcfSSatish Balay    Output Parameters:
748f4c1ad5cSStefano Zampini +  J    - Jacobian matrix
749f4c1ad5cSStefano Zampini -  Jpre - Preconditioning matrix
750a7e14dcfSSatish Balay 
751a7e14dcfSSatish Balay    Notes:
752a7e14dcfSSatish Balay    Most users should not need to explicitly call this routine, as it
753a7e14dcfSSatish Balay    is used internally within the minimization solvers.
754a7e14dcfSSatish Balay 
755a7e14dcfSSatish Balay    Level: developer
756a7e14dcfSSatish Balay 
757a7e14dcfSSatish Balay .seealso:  TaoComputeObjective(), TaoComputeObjectiveAndGradient(), TaoSetJacobianStateRoutine(), TaoComputeJacobianDesign(), TaoSetStateDesignIS()
758a7e14dcfSSatish Balay @*/
759ffad9901SBarry Smith PetscErrorCode TaoComputeJacobianInequality(Tao tao, Vec X, Mat J, Mat Jpre)
760a7e14dcfSSatish Balay {
761a7e14dcfSSatish Balay   PetscErrorCode ierr;
76287f595a5SBarry Smith 
763a7e14dcfSSatish Balay   PetscFunctionBegin;
764441846f8SBarry Smith   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
765a7e14dcfSSatish Balay   PetscValidHeaderSpecific(X, VEC_CLASSID,2);
766a7e14dcfSSatish Balay   PetscCheckSameComm(tao,1,X,2);
76787f595a5SBarry Smith   if (!tao->ops->computejacobianinequality) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Must call TaoSetJacobianInequality() first");
768a7e14dcfSSatish Balay   ++tao->njac_inequality;
769f4c1ad5cSStefano Zampini   ierr = VecLockPush(X);CHKERRQ(ierr);
7700ebee16dSLisandro Dalcin   ierr = PetscLogEventBegin(TAO_JacobianEval,tao,X,J,Jpre);CHKERRQ(ierr);
771441846f8SBarry Smith   PetscStackPush("Tao user Jacobian(inequality) function");
772ffad9901SBarry Smith   ierr = (*tao->ops->computejacobianinequality)(tao,X,J,Jpre,tao->user_jac_inequalityP);CHKERRQ(ierr);
773a7e14dcfSSatish Balay   PetscStackPop;
7740ebee16dSLisandro Dalcin   ierr = PetscLogEventEnd(TAO_JacobianEval,tao,X,J,Jpre);CHKERRQ(ierr);
775f4c1ad5cSStefano Zampini   ierr = VecLockPop(X);CHKERRQ(ierr);
776a7e14dcfSSatish Balay   PetscFunctionReturn(0);
777a7e14dcfSSatish Balay }
778a7e14dcfSSatish Balay 
779a7e14dcfSSatish Balay /*@C
780a7e14dcfSSatish Balay    TaoSetJacobianEqualityRoutine - Sets the function to compute the Jacobian
781a7e14dcfSSatish Balay    (and its inverse) of the constraint function with respect to the equality variables.
782a7e14dcfSSatish Balay    Used only for pde-constrained optimization.
783a7e14dcfSSatish Balay 
784441846f8SBarry Smith    Logically collective on Tao
785a7e14dcfSSatish Balay 
786a7e14dcfSSatish Balay    Input Parameters:
787441846f8SBarry Smith +  tao  - the Tao context
788a7e14dcfSSatish Balay .  J    - Matrix used for the jacobian
789a7e14dcfSSatish Balay .  Jpre - Matrix that will be used operated on by PETSc preconditioner, can be same as J.
790f4c1ad5cSStefano Zampini .  func - Jacobian evaluation routine
791a7e14dcfSSatish Balay -  ctx  - [optional] user-defined context for private data for the
7926c23d075SBarry Smith           Jacobian evaluation routine (may be NULL)
793a7e14dcfSSatish Balay 
794f4c1ad5cSStefano Zampini    Calling sequence of func:
795f4c1ad5cSStefano Zampini $    func(Tao tao,Vec x,Mat J,Mat Jpre,void *ctx);
796a7e14dcfSSatish Balay 
797441846f8SBarry Smith +  tao  - the Tao  context
798a7e14dcfSSatish Balay .  x    - input vector
799a7e14dcfSSatish Balay .  J    - Jacobian matrix
800a7e14dcfSSatish Balay .  Jpre - preconditioner matrix, usually the same as J
801a7e14dcfSSatish Balay -  ctx  - [optional] user-defined Jacobian context
802a7e14dcfSSatish Balay 
803a7e14dcfSSatish Balay    Level: intermediate
804f4c1ad5cSStefano Zampini 
805f4c1ad5cSStefano Zampini .seealso: TaoComputeJacobianEquality(), TaoSetJacobianDesignRoutine(), TaoSetEqualityDesignIS()
806a7e14dcfSSatish Balay @*/
807ffad9901SBarry Smith PetscErrorCode TaoSetJacobianEqualityRoutine(Tao tao, Mat J, Mat Jpre, PetscErrorCode (*func)(Tao, Vec, Mat, Mat,void*), void *ctx)
808a7e14dcfSSatish Balay {
809a7e14dcfSSatish Balay   PetscErrorCode ierr;
81045cf516eSBarry Smith 
811a7e14dcfSSatish Balay   PetscFunctionBegin;
812441846f8SBarry Smith   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
813a7e14dcfSSatish Balay   if (J) {
814a7e14dcfSSatish Balay     PetscValidHeaderSpecific(J,MAT_CLASSID,2);
815a7e14dcfSSatish Balay     PetscCheckSameComm(tao,1,J,2);
816a7e14dcfSSatish Balay   }
817a7e14dcfSSatish Balay   if (Jpre) {
818a7e14dcfSSatish Balay     PetscValidHeaderSpecific(Jpre,MAT_CLASSID,3);
819a7e14dcfSSatish Balay     PetscCheckSameComm(tao,1,Jpre,3);
820a7e14dcfSSatish Balay   }
821a7e14dcfSSatish Balay   if (ctx) {
822a7e14dcfSSatish Balay     tao->user_jac_equalityP = ctx;
823a7e14dcfSSatish Balay   }
824a7e14dcfSSatish Balay   if (func) {
825a7e14dcfSSatish Balay     tao->ops->computejacobianequality = func;
826a7e14dcfSSatish Balay   }
827a7e14dcfSSatish Balay   if (J) {
828a7e14dcfSSatish Balay     ierr = PetscObjectReference((PetscObject)J);CHKERRQ(ierr);
82945cf516eSBarry Smith     ierr = MatDestroy(&tao->jacobian_equality);CHKERRQ(ierr);
830a7e14dcfSSatish Balay     tao->jacobian_equality = J;
831a7e14dcfSSatish Balay   }
832a7e14dcfSSatish Balay   if (Jpre) {
833a7e14dcfSSatish Balay     ierr = PetscObjectReference((PetscObject)Jpre);CHKERRQ(ierr);
83445cf516eSBarry Smith     ierr = MatDestroy(&tao->jacobian_equality_pre);CHKERRQ(ierr);
835a7e14dcfSSatish Balay     tao->jacobian_equality_pre=Jpre;
836a7e14dcfSSatish Balay   }
837a7e14dcfSSatish Balay   PetscFunctionReturn(0);
838a7e14dcfSSatish Balay }
839a7e14dcfSSatish Balay 
840a7e14dcfSSatish Balay /*@C
841a7e14dcfSSatish Balay    TaoSetJacobianInequalityRoutine - Sets the function to compute the Jacobian
842a7e14dcfSSatish Balay    (and its inverse) of the constraint function with respect to the inequality variables.
843a7e14dcfSSatish Balay    Used only for pde-constrained optimization.
844a7e14dcfSSatish Balay 
845441846f8SBarry Smith    Logically collective on Tao
846a7e14dcfSSatish Balay 
847a7e14dcfSSatish Balay    Input Parameters:
848441846f8SBarry Smith +  tao  - the Tao context
849a7e14dcfSSatish Balay .  J    - Matrix used for the jacobian
850a7e14dcfSSatish Balay .  Jpre - Matrix that will be used operated on by PETSc preconditioner, can be same as J.
851f4c1ad5cSStefano Zampini .  func - Jacobian evaluation routine
852a7e14dcfSSatish Balay -  ctx  - [optional] user-defined context for private data for the
8536c23d075SBarry Smith           Jacobian evaluation routine (may be NULL)
854a7e14dcfSSatish Balay 
855f4c1ad5cSStefano Zampini    Calling sequence of func:
856f4c1ad5cSStefano Zampini $    func(Tao tao,Vec x,Mat J,Mat Jpre,void *ctx);
857a7e14dcfSSatish Balay 
858441846f8SBarry Smith +  tao  - the Tao  context
859a7e14dcfSSatish Balay .  x    - input vector
860a7e14dcfSSatish Balay .  J    - Jacobian matrix
861a7e14dcfSSatish Balay .  Jpre - preconditioner matrix, usually the same as J
862a7e14dcfSSatish Balay -  ctx  - [optional] user-defined Jacobian context
863a7e14dcfSSatish Balay 
864a7e14dcfSSatish Balay    Level: intermediate
865f4c1ad5cSStefano Zampini 
866f4c1ad5cSStefano Zampini .seealso: TaoComputeJacobianInequality(), TaoSetJacobianDesignRoutine(), TaoSetInequalityDesignIS()
867a7e14dcfSSatish Balay @*/
868ffad9901SBarry Smith PetscErrorCode TaoSetJacobianInequalityRoutine(Tao tao, Mat J, Mat Jpre, PetscErrorCode (*func)(Tao, Vec, Mat, Mat,void*), void *ctx)
869a7e14dcfSSatish Balay {
870a7e14dcfSSatish Balay   PetscErrorCode ierr;
871f4c1ad5cSStefano Zampini 
872a7e14dcfSSatish Balay   PetscFunctionBegin;
873441846f8SBarry Smith   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
874a7e14dcfSSatish Balay   if (J) {
875a7e14dcfSSatish Balay     PetscValidHeaderSpecific(J,MAT_CLASSID,2);
876a7e14dcfSSatish Balay     PetscCheckSameComm(tao,1,J,2);
877a7e14dcfSSatish Balay   }
878a7e14dcfSSatish Balay   if (Jpre) {
879a7e14dcfSSatish Balay     PetscValidHeaderSpecific(Jpre,MAT_CLASSID,3);
880a7e14dcfSSatish Balay     PetscCheckSameComm(tao,1,Jpre,3);
881a7e14dcfSSatish Balay   }
882a7e14dcfSSatish Balay   if (ctx) {
883a7e14dcfSSatish Balay     tao->user_jac_inequalityP = ctx;
884a7e14dcfSSatish Balay   }
885a7e14dcfSSatish Balay   if (func) {
886a7e14dcfSSatish Balay     tao->ops->computejacobianinequality = func;
887a7e14dcfSSatish Balay   }
888a7e14dcfSSatish Balay   if (J) {
889a7e14dcfSSatish Balay     ierr = PetscObjectReference((PetscObject)J);CHKERRQ(ierr);
89045cf516eSBarry Smith     ierr = MatDestroy(&tao->jacobian_inequality);CHKERRQ(ierr);
891a7e14dcfSSatish Balay     tao->jacobian_inequality = J;
892a7e14dcfSSatish Balay   }
893a7e14dcfSSatish Balay   if (Jpre) {
894a7e14dcfSSatish Balay     ierr = PetscObjectReference((PetscObject)Jpre);CHKERRQ(ierr);
89545cf516eSBarry Smith     ierr = MatDestroy(&tao->jacobian_inequality_pre);CHKERRQ(ierr);
896a7e14dcfSSatish Balay     tao->jacobian_inequality_pre=Jpre;
897a7e14dcfSSatish Balay   }
898a7e14dcfSSatish Balay   PetscFunctionReturn(0);
899a7e14dcfSSatish Balay }
900