xref: /petsc/src/tao/interface/taosolver_hj.c (revision b9e7e5c1f1fe158a0312e1538d69d2999b53c077)
1af0996ceSBarry Smith #include <petsc/private/taoimpl.h> /*I "petsctao.h" I*/
2a7e14dcfSSatish Balay 
38e85b1b3SXiang Huang 
4a7e14dcfSSatish Balay /*@C
5a7e14dcfSSatish Balay    TaoSetHessianRoutine - Sets the function to compute the Hessian as well as the location to store the matrix.
6a7e14dcfSSatish Balay 
7441846f8SBarry Smith    Logically collective on Tao
8a7e14dcfSSatish Balay 
9a7e14dcfSSatish Balay    Input Parameters:
10441846f8SBarry Smith +  tao  - the Tao context
11a7e14dcfSSatish Balay .  H    - Matrix used for the hessian
12a7e14dcfSSatish Balay .  Hpre - Matrix that will be used operated on by preconditioner, can be same as H
13f4c1ad5cSStefano Zampini .  func - Hessian evaluation routine
14a7e14dcfSSatish Balay -  ctx  - [optional] user-defined context for private data for the
156c23d075SBarry Smith          Hessian evaluation routine (may be NULL)
16a7e14dcfSSatish Balay 
17f4c1ad5cSStefano Zampini    Calling sequence of func:
18f4c1ad5cSStefano Zampini $    func(Tao tao,Vec x,Mat H,Mat Hpre,void *ctx);
19a7e14dcfSSatish Balay 
20441846f8SBarry Smith +  tao  - the Tao  context
21a7e14dcfSSatish Balay .  x    - input vector
22a7e14dcfSSatish Balay .  H    - Hessian matrix
23a7e14dcfSSatish Balay .  Hpre - preconditioner matrix, usually the same as H
24a7e14dcfSSatish Balay -  ctx  - [optional] user-defined Hessian context
25a7e14dcfSSatish Balay 
26a7e14dcfSSatish Balay    Level: beginner
27a7e14dcfSSatish Balay @*/
28ffad9901SBarry Smith PetscErrorCode TaoSetHessianRoutine(Tao tao, Mat H, Mat Hpre, PetscErrorCode (*func)(Tao, Vec, Mat, Mat, void*), void *ctx)
29a7e14dcfSSatish Balay {
30a7e14dcfSSatish Balay   PetscErrorCode ierr;
3145cf516eSBarry Smith 
32a7e14dcfSSatish Balay   PetscFunctionBegin;
33441846f8SBarry Smith   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
34a7e14dcfSSatish Balay   if (H) {
35a7e14dcfSSatish Balay     PetscValidHeaderSpecific(H,MAT_CLASSID,2);
36a7e14dcfSSatish Balay     PetscCheckSameComm(tao,1,H,2);
37a7e14dcfSSatish Balay   }
38a7e14dcfSSatish Balay   if (Hpre) {
39a7e14dcfSSatish Balay     PetscValidHeaderSpecific(Hpre,MAT_CLASSID,3);
40a7e14dcfSSatish Balay     PetscCheckSameComm(tao,1,Hpre,3);
41a7e14dcfSSatish Balay   }
42a7e14dcfSSatish Balay   if (ctx) {
43a7e14dcfSSatish Balay     tao->user_hessP = ctx;
44a7e14dcfSSatish Balay   }
45a7e14dcfSSatish Balay   if (func) {
46a7e14dcfSSatish Balay     tao->ops->computehessian = func;
47a7e14dcfSSatish Balay   }
48a7e14dcfSSatish Balay   if (H) {
49a7e14dcfSSatish Balay     ierr = PetscObjectReference((PetscObject)H);CHKERRQ(ierr);
5045cf516eSBarry Smith     ierr = MatDestroy(&tao->hessian);CHKERRQ(ierr);
51a7e14dcfSSatish Balay     tao->hessian = H;
52a7e14dcfSSatish Balay   }
53a7e14dcfSSatish Balay   if (Hpre) {
54a7e14dcfSSatish Balay     ierr = PetscObjectReference((PetscObject)Hpre);CHKERRQ(ierr);
5545cf516eSBarry Smith     ierr = MatDestroy(&tao->hessian_pre);CHKERRQ(ierr);
56a7e14dcfSSatish Balay     tao->hessian_pre = Hpre;
57a7e14dcfSSatish Balay   }
58a7e14dcfSSatish Balay   PetscFunctionReturn(0);
59a7e14dcfSSatish Balay }
60a7e14dcfSSatish Balay 
6109baa881SHong Zhang PetscErrorCode TaoTestHessian(Tao tao)
6209baa881SHong Zhang {
6309baa881SHong Zhang   Mat               A,B,C,D,hessian;
6409baa881SHong Zhang   Vec               x = tao->solution;
6509baa881SHong Zhang   PetscErrorCode    ierr;
6609baa881SHong Zhang   PetscReal         nrm,gnorm;
6709baa881SHong Zhang   PetscReal         threshold = 1.e-5;
6809baa881SHong Zhang   PetscInt          m,n,M,N;
6909baa881SHong Zhang   PetscBool         complete_print = PETSC_FALSE,test = PETSC_FALSE,flg;
70f49d1c87SHong Zhang   PetscViewer       viewer,mviewer;
7109baa881SHong Zhang   MPI_Comm          comm;
7209baa881SHong Zhang   PetscInt          tabs;
7309baa881SHong Zhang   static PetscBool  directionsprinted = PETSC_FALSE;
74f49d1c87SHong Zhang   PetscViewerFormat format;
7509baa881SHong Zhang 
7609baa881SHong Zhang   PetscFunctionBegin;
7709baa881SHong Zhang   ierr = PetscObjectOptionsBegin((PetscObject)tao);CHKERRQ(ierr);
7809baa881SHong Zhang   ierr = PetscOptionsName("-tao_test_hessian","Compare hand-coded and finite difference Hessians","None",&test);CHKERRQ(ierr);
7909baa881SHong Zhang   ierr = PetscOptionsReal("-tao_test_hessian", "Threshold for element difference between hand-coded and finite difference being meaningful","None",threshold,&threshold,NULL);CHKERRQ(ierr);
80f49d1c87SHong 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);
8109baa881SHong Zhang   ierr = PetscOptionsEnd();CHKERRQ(ierr);
8209baa881SHong Zhang   if (!test) PetscFunctionReturn(0);
8309baa881SHong Zhang 
8409baa881SHong Zhang   ierr = PetscObjectGetComm((PetscObject)tao,&comm);CHKERRQ(ierr);
8509baa881SHong Zhang   ierr = PetscViewerASCIIGetStdout(comm,&viewer);CHKERRQ(ierr);
8609baa881SHong Zhang   ierr = PetscViewerASCIIGetTab(viewer, &tabs);CHKERRQ(ierr);
8709baa881SHong Zhang   ierr = PetscViewerASCIISetTab(viewer, ((PetscObject)tao)->tablevel);CHKERRQ(ierr);
8809baa881SHong Zhang   ierr = PetscViewerASCIIPrintf(viewer,"  ---------- Testing Hessian -------------\n");CHKERRQ(ierr);
8909baa881SHong Zhang   if (!complete_print && !directionsprinted) {
9009baa881SHong Zhang     ierr = PetscViewerASCIIPrintf(viewer,"  Run with -tao_test_hessian_view and optionally -tao_test_hessian <threshold> to show difference\n");CHKERRQ(ierr);
9109baa881SHong Zhang     ierr = PetscViewerASCIIPrintf(viewer,"    of hand-coded and finite difference Hessian entries greater than <threshold>.\n");CHKERRQ(ierr);
9209baa881SHong Zhang   }
9309baa881SHong Zhang   if (!directionsprinted) {
9409baa881SHong Zhang     ierr = PetscViewerASCIIPrintf(viewer,"  Testing hand-coded Hessian, if (for double precision runs) ||J - Jfd||_F/||J||_F is\n");CHKERRQ(ierr);
9509baa881SHong Zhang     ierr = PetscViewerASCIIPrintf(viewer,"    O(1.e-8), the hand-coded Hessian is probably correct.\n");CHKERRQ(ierr);
9609baa881SHong Zhang     directionsprinted = PETSC_TRUE;
9709baa881SHong Zhang   }
98f49d1c87SHong Zhang   if (complete_print) {
99f49d1c87SHong Zhang     ierr = PetscViewerPushFormat(mviewer,format);CHKERRQ(ierr);
100f49d1c87SHong Zhang   }
10109baa881SHong Zhang 
10209baa881SHong Zhang   ierr = PetscObjectTypeCompare((PetscObject)tao->hessian,MATMFFD,&flg);CHKERRQ(ierr);
10309baa881SHong Zhang   if (!flg) hessian = tao->hessian;
10409baa881SHong Zhang   else hessian = tao->hessian_pre;
10509baa881SHong Zhang 
10609baa881SHong Zhang   while (hessian) {
107*b9e7e5c1SBarry Smith     ierr = PetscObjectBaseTypeCompareAny((PetscObject)hessian,&flg,MATSEQAIJ,MATMPIAIJ,MATSEQDENSE,MATMPIDENSE,MATSEQBAIJ,MATMPIBAIJ,MATSEQSBAIJ,MATMPIBAIJ,"");CHKERRQ(ierr);
10809baa881SHong Zhang     if (flg) {
10909baa881SHong Zhang       A    = hessian;
11009baa881SHong Zhang       ierr = PetscObjectReference((PetscObject)A);CHKERRQ(ierr);
11109baa881SHong Zhang     } else {
1120bacdadaSStefano Zampini       ierr = MatComputeOperator(hessian,MATAIJ,&A);CHKERRQ(ierr);
11309baa881SHong Zhang     }
11409baa881SHong Zhang 
11509baa881SHong Zhang     ierr = MatCreate(PetscObjectComm((PetscObject)A),&B);CHKERRQ(ierr);
11609baa881SHong Zhang     ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
11709baa881SHong Zhang     ierr = MatGetLocalSize(A,&m,&n);CHKERRQ(ierr);
11809baa881SHong Zhang     ierr = MatSetSizes(B,m,n,M,N);CHKERRQ(ierr);
11909baa881SHong Zhang     ierr = MatSetType(B,((PetscObject)A)->type_name);CHKERRQ(ierr);
12009baa881SHong Zhang     ierr = MatSetUp(B);CHKERRQ(ierr);
12109baa881SHong Zhang     ierr = MatSetOption(B,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_FALSE);CHKERRQ(ierr);
12209baa881SHong Zhang 
12309baa881SHong Zhang     ierr = TaoDefaultComputeHessian(tao,x,B,B,NULL);CHKERRQ(ierr);
12409baa881SHong Zhang 
12509baa881SHong Zhang     ierr = MatDuplicate(B,MAT_COPY_VALUES,&D);CHKERRQ(ierr);
12609baa881SHong Zhang     ierr = MatAYPX(D,-1.0,A,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr);
12709baa881SHong Zhang     ierr = MatNorm(D,NORM_FROBENIUS,&nrm);CHKERRQ(ierr);
12809baa881SHong Zhang     ierr = MatNorm(A,NORM_FROBENIUS,&gnorm);CHKERRQ(ierr);
12909baa881SHong Zhang     ierr = MatDestroy(&D);CHKERRQ(ierr);
13009baa881SHong Zhang     if (!gnorm) gnorm = 1; /* just in case */
13109baa881SHong Zhang     ierr = PetscViewerASCIIPrintf(viewer,"  ||H - Hfd||_F/||H||_F = %g, ||H - Hfd||_F = %g\n",(double)(nrm/gnorm),(double)nrm);CHKERRQ(ierr);
13209baa881SHong Zhang 
13309baa881SHong Zhang     if (complete_print) {
13409baa881SHong Zhang       ierr = PetscViewerASCIIPrintf(viewer,"  Hand-coded Hessian ----------\n");CHKERRQ(ierr);
135f49d1c87SHong Zhang       ierr = MatView(hessian,mviewer);CHKERRQ(ierr);
13609baa881SHong Zhang       ierr = PetscViewerASCIIPrintf(viewer,"  Finite difference Hessian ----------\n");CHKERRQ(ierr);
137f49d1c87SHong Zhang       ierr = MatView(B,mviewer);CHKERRQ(ierr);
13809baa881SHong Zhang     }
13909baa881SHong Zhang 
14009baa881SHong Zhang     if (complete_print) {
14109baa881SHong Zhang       PetscInt          Istart, Iend, *ccols, bncols, cncols, j, row;
14209baa881SHong Zhang       PetscScalar       *cvals;
14309baa881SHong Zhang       const PetscInt    *bcols;
14409baa881SHong Zhang       const PetscScalar *bvals;
14509baa881SHong Zhang 
14609baa881SHong Zhang       ierr = MatAYPX(B,-1.0,A,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr);
14709baa881SHong Zhang       ierr = MatCreate(PetscObjectComm((PetscObject)A),&C);CHKERRQ(ierr);
14809baa881SHong Zhang       ierr = MatSetSizes(C,m,n,M,N);CHKERRQ(ierr);
14909baa881SHong Zhang       ierr = MatSetType(C,((PetscObject)A)->type_name);CHKERRQ(ierr);
15009baa881SHong Zhang       ierr = MatSetUp(C);CHKERRQ(ierr);
15109baa881SHong Zhang       ierr = MatSetOption(C,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_FALSE);CHKERRQ(ierr);
15209baa881SHong Zhang       ierr = MatGetOwnershipRange(B,&Istart,&Iend);CHKERRQ(ierr);
15309baa881SHong Zhang 
15409baa881SHong Zhang       for (row = Istart; row < Iend; row++) {
15509baa881SHong Zhang         ierr = MatGetRow(B,row,&bncols,&bcols,&bvals);CHKERRQ(ierr);
15609baa881SHong Zhang         ierr = PetscMalloc2(bncols,&ccols,bncols,&cvals);CHKERRQ(ierr);
15709baa881SHong Zhang         for (j = 0, cncols = 0; j < bncols; j++) {
15809baa881SHong Zhang           if (PetscAbsScalar(bvals[j]) > threshold) {
15909baa881SHong Zhang             ccols[cncols] = bcols[j];
16009baa881SHong Zhang             cvals[cncols] = bvals[j];
16109baa881SHong Zhang             cncols += 1;
16209baa881SHong Zhang           }
16309baa881SHong Zhang         }
16409baa881SHong Zhang         if (cncols) {
16509baa881SHong Zhang           ierr = MatSetValues(C,1,&row,cncols,ccols,cvals,INSERT_VALUES);CHKERRQ(ierr);
16609baa881SHong Zhang         }
16709baa881SHong Zhang         ierr = MatRestoreRow(B,row,&bncols,&bcols,&bvals);CHKERRQ(ierr);
16809baa881SHong Zhang         ierr = PetscFree2(ccols,cvals);CHKERRQ(ierr);
16909baa881SHong Zhang       }
17009baa881SHong Zhang       ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
17109baa881SHong Zhang       ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
17209baa881SHong Zhang       ierr = PetscViewerASCIIPrintf(viewer,"  Finite-difference minus hand-coded Hessian with tolerance %g ----------\n",(double)threshold);CHKERRQ(ierr);
173f49d1c87SHong Zhang       ierr = MatView(C,mviewer);CHKERRQ(ierr);
17409baa881SHong Zhang       ierr = MatDestroy(&C);CHKERRQ(ierr);
17509baa881SHong Zhang     }
17609baa881SHong Zhang     ierr = MatDestroy(&A);CHKERRQ(ierr);
17709baa881SHong Zhang     ierr = MatDestroy(&B);CHKERRQ(ierr);
17809baa881SHong Zhang 
17909baa881SHong Zhang     if (hessian != tao->hessian_pre) {
18009baa881SHong Zhang       hessian = tao->hessian_pre;
18109baa881SHong Zhang       ierr = PetscViewerASCIIPrintf(viewer,"  ---------- Testing Hessian for preconditioner -------------\n");CHKERRQ(ierr);
18209baa881SHong Zhang     } else hessian = NULL;
18309baa881SHong Zhang   }
184f49d1c87SHong Zhang   if (complete_print) {
185f49d1c87SHong Zhang     ierr = PetscViewerPopFormat(mviewer);CHKERRQ(ierr);
186f49d1c87SHong Zhang   }
18709baa881SHong Zhang   ierr = PetscViewerASCIISetTab(viewer,tabs);CHKERRQ(ierr);
18809baa881SHong Zhang   PetscFunctionReturn(0);
18909baa881SHong Zhang }
19009baa881SHong Zhang 
191a7e14dcfSSatish Balay /*@C
192a7e14dcfSSatish Balay    TaoComputeHessian - Computes the Hessian matrix that has been
193a7e14dcfSSatish Balay    set with TaoSetHessianRoutine().
194a7e14dcfSSatish Balay 
195441846f8SBarry Smith    Collective on Tao
196a7e14dcfSSatish Balay 
197a7e14dcfSSatish Balay    Input Parameters:
198f4c1ad5cSStefano Zampini +  tao - the Tao solver context
199f4c1ad5cSStefano Zampini -  X   - input vector
200a7e14dcfSSatish Balay 
201a7e14dcfSSatish Balay    Output Parameters:
202a7e14dcfSSatish Balay +  H    - Hessian matrix
203aa6c7ce3SBarry Smith -  Hpre - Preconditioning matrix
204a7e14dcfSSatish Balay 
20509baa881SHong Zhang    Options Database Keys:
20609baa881SHong Zhang +     -tao_test_hessian - compare the user provided Hessian with one compute via finite differences to check for errors
20709baa881SHong 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
208dfe02fe6SHong 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
20909baa881SHong Zhang 
210a7e14dcfSSatish Balay    Notes:
211a7e14dcfSSatish Balay    Most users should not need to explicitly call this routine, as it
212a7e14dcfSSatish Balay    is used internally within the minimization solvers.
213a7e14dcfSSatish Balay 
214a7e14dcfSSatish Balay    TaoComputeHessian() is typically used within minimization
215a7e14dcfSSatish Balay    implementations, so most users would not generally call this routine
216a7e14dcfSSatish Balay    themselves.
217a7e14dcfSSatish Balay 
21809baa881SHong Zhang    Developer Notes:
21909baa881SHong Zhang    The Hessian test mechanism follows SNESTestJacobian().
22009baa881SHong Zhang 
221a7e14dcfSSatish Balay    Level: developer
222a7e14dcfSSatish Balay 
223f4c1ad5cSStefano Zampini .seealso: TaoComputeObjective(), TaoComputeObjectiveAndGradient(), TaoSetHessianRoutine()
224a7e14dcfSSatish Balay @*/
225ffad9901SBarry Smith PetscErrorCode TaoComputeHessian(Tao tao, Vec X, Mat H, Mat Hpre)
226a7e14dcfSSatish Balay {
227a7e14dcfSSatish Balay   PetscErrorCode ierr;
22887f595a5SBarry Smith 
229a7e14dcfSSatish Balay   PetscFunctionBegin;
230441846f8SBarry Smith   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
231a7e14dcfSSatish Balay   PetscValidHeaderSpecific(X, VEC_CLASSID,2);
232a7e14dcfSSatish Balay   PetscCheckSameComm(tao,1,X,2);
233f4c1ad5cSStefano Zampini   if (!tao->ops->computehessian) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Must call TaoSetHessianRoutine() first");
234a7e14dcfSSatish Balay   ++tao->nhess;
2358860a134SJunchao Zhang   ierr = VecLockReadPush(X);CHKERRQ(ierr);
2360ebee16dSLisandro Dalcin   ierr = PetscLogEventBegin(TAO_HessianEval,tao,X,H,Hpre);CHKERRQ(ierr);
237441846f8SBarry Smith   PetscStackPush("Tao user Hessian function");
238ffad9901SBarry Smith   ierr = (*tao->ops->computehessian)(tao,X,H,Hpre,tao->user_hessP);CHKERRQ(ierr);
239a7e14dcfSSatish Balay   PetscStackPop;
2400ebee16dSLisandro Dalcin   ierr = PetscLogEventEnd(TAO_HessianEval,tao,X,H,Hpre);CHKERRQ(ierr);
2418860a134SJunchao Zhang   ierr = VecLockReadPop(X);CHKERRQ(ierr);
24209baa881SHong Zhang 
24309baa881SHong Zhang   ierr = TaoTestHessian(tao);CHKERRQ(ierr);
244a7e14dcfSSatish Balay   PetscFunctionReturn(0);
245a7e14dcfSSatish Balay }
246a7e14dcfSSatish Balay 
247a7e14dcfSSatish Balay /*@C
248a7e14dcfSSatish Balay    TaoComputeJacobian - Computes the Jacobian matrix that has been
249a7e14dcfSSatish Balay    set with TaoSetJacobianRoutine().
250a7e14dcfSSatish Balay 
251441846f8SBarry Smith    Collective on Tao
252a7e14dcfSSatish Balay 
253a7e14dcfSSatish Balay    Input Parameters:
254f4c1ad5cSStefano Zampini +  tao - the Tao solver context
255f4c1ad5cSStefano Zampini -  X   - input vector
256a7e14dcfSSatish Balay 
257a7e14dcfSSatish Balay    Output Parameters:
258f4c1ad5cSStefano Zampini +  J    - Jacobian matrix
259f4c1ad5cSStefano Zampini -  Jpre - Preconditioning matrix
260a7e14dcfSSatish Balay 
261a7e14dcfSSatish Balay    Notes:
262a7e14dcfSSatish Balay    Most users should not need to explicitly call this routine, as it
263a7e14dcfSSatish Balay    is used internally within the minimization solvers.
264a7e14dcfSSatish Balay 
265a7e14dcfSSatish Balay    TaoComputeJacobian() is typically used within minimization
266a7e14dcfSSatish Balay    implementations, so most users would not generally call this routine
267a7e14dcfSSatish Balay    themselves.
268a7e14dcfSSatish Balay 
269a7e14dcfSSatish Balay    Level: developer
270a7e14dcfSSatish Balay 
271f4c1ad5cSStefano Zampini .seealso: TaoComputeObjective(), TaoComputeObjectiveAndGradient(), TaoSetJacobianRoutine()
272a7e14dcfSSatish Balay @*/
273ffad9901SBarry Smith PetscErrorCode TaoComputeJacobian(Tao tao, Vec X, Mat J, Mat Jpre)
274a7e14dcfSSatish Balay {
275a7e14dcfSSatish Balay   PetscErrorCode ierr;
27687f595a5SBarry Smith 
277a7e14dcfSSatish Balay   PetscFunctionBegin;
278441846f8SBarry Smith   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
279a7e14dcfSSatish Balay   PetscValidHeaderSpecific(X, VEC_CLASSID,2);
280a7e14dcfSSatish Balay   PetscCheckSameComm(tao,1,X,2);
28187f595a5SBarry Smith   if (!tao->ops->computejacobian) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Must call TaoSetJacobian() first");
282a7e14dcfSSatish Balay   ++tao->njac;
2838860a134SJunchao Zhang   ierr = VecLockReadPush(X);CHKERRQ(ierr);
2840ebee16dSLisandro Dalcin   ierr = PetscLogEventBegin(TAO_JacobianEval,tao,X,J,Jpre);CHKERRQ(ierr);
285441846f8SBarry Smith   PetscStackPush("Tao user Jacobian function");
286ffad9901SBarry Smith   ierr = (*tao->ops->computejacobian)(tao,X,J,Jpre,tao->user_jacP);CHKERRQ(ierr);
287a7e14dcfSSatish Balay   PetscStackPop;
2880ebee16dSLisandro Dalcin   ierr = PetscLogEventEnd(TAO_JacobianEval,tao,X,J,Jpre);CHKERRQ(ierr);
2898860a134SJunchao Zhang   ierr = VecLockReadPop(X);CHKERRQ(ierr);
290a7e14dcfSSatish Balay   PetscFunctionReturn(0);
291a7e14dcfSSatish Balay }
292a7e14dcfSSatish Balay 
293a7e14dcfSSatish Balay /*@C
2944a48860cSAlp Dener    TaoComputeResidualJacobian - Computes the least-squares residual Jacobian matrix that has been
295a6fed868SAlp Dener    set with TaoSetJacobianResidual().
2964a48860cSAlp Dener 
2974a48860cSAlp Dener    Collective on Tao
2984a48860cSAlp Dener 
2994a48860cSAlp Dener    Input Parameters:
3004a48860cSAlp Dener +  tao - the Tao solver context
3014a48860cSAlp Dener -  X   - input vector
3024a48860cSAlp Dener 
3034a48860cSAlp Dener    Output Parameters:
3044a48860cSAlp Dener +  J    - Jacobian matrix
3054a48860cSAlp Dener -  Jpre - Preconditioning matrix
3064a48860cSAlp Dener 
3074a48860cSAlp Dener    Notes:
3084a48860cSAlp Dener    Most users should not need to explicitly call this routine, as it
3094a48860cSAlp Dener    is used internally within the minimization solvers.
3104a48860cSAlp Dener 
3114a48860cSAlp Dener    TaoComputeResidualJacobian() is typically used within least-squares
3124a48860cSAlp Dener    implementations, so most users would not generally call this routine
3134a48860cSAlp Dener    themselves.
3144a48860cSAlp Dener 
3154a48860cSAlp Dener    Level: developer
3164a48860cSAlp Dener 
317a6fed868SAlp Dener .seealso: TaoComputeResidual(), TaoSetJacobianResidual()
3184a48860cSAlp Dener @*/
3194a48860cSAlp Dener PetscErrorCode TaoComputeResidualJacobian(Tao tao, Vec X, Mat J, Mat Jpre)
3204a48860cSAlp Dener {
3214a48860cSAlp Dener   PetscErrorCode ierr;
3224a48860cSAlp Dener 
3234a48860cSAlp Dener   PetscFunctionBegin;
3244a48860cSAlp Dener   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
3254a48860cSAlp Dener   PetscValidHeaderSpecific(X, VEC_CLASSID,2);
3264a48860cSAlp Dener   PetscCheckSameComm(tao,1,X,2);
3274a48860cSAlp Dener   if (!tao->ops->computeresidualjacobian) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Must call TaoSetResidualJacobian() first");
3284a48860cSAlp Dener   ++tao->njac;
3298860a134SJunchao Zhang   ierr = VecLockReadPush(X);CHKERRQ(ierr);
3304a48860cSAlp Dener   ierr = PetscLogEventBegin(TAO_JacobianEval,tao,X,J,Jpre);CHKERRQ(ierr);
3314a48860cSAlp Dener   PetscStackPush("Tao user least-squares residual Jacobian function");
3324a48860cSAlp Dener   ierr = (*tao->ops->computeresidualjacobian)(tao,X,J,Jpre,tao->user_lsjacP);CHKERRQ(ierr);
3334a48860cSAlp Dener   PetscStackPop;
3344a48860cSAlp Dener   ierr = PetscLogEventEnd(TAO_JacobianEval,tao,X,J,Jpre);CHKERRQ(ierr);
3358860a134SJunchao Zhang   ierr = VecLockReadPop(X);CHKERRQ(ierr);
3364a48860cSAlp Dener   PetscFunctionReturn(0);
3374a48860cSAlp Dener }
3384a48860cSAlp Dener 
3394a48860cSAlp Dener /*@C
340a7e14dcfSSatish Balay    TaoComputeJacobianState - Computes the Jacobian matrix that has been
341a7e14dcfSSatish Balay    set with TaoSetJacobianStateRoutine().
342a7e14dcfSSatish Balay 
343441846f8SBarry Smith    Collective on Tao
344a7e14dcfSSatish Balay 
345a7e14dcfSSatish Balay    Input Parameters:
346f4c1ad5cSStefano Zampini +  tao - the Tao solver context
347f4c1ad5cSStefano Zampini -  X   - input vector
348a7e14dcfSSatish Balay 
349a7e14dcfSSatish Balay    Output Parameters:
350f4c1ad5cSStefano Zampini +  Jpre - Jacobian matrix
351f4c1ad5cSStefano Zampini -  Jinv - Preconditioning matrix
352a7e14dcfSSatish Balay 
353a7e14dcfSSatish Balay    Notes:
354a7e14dcfSSatish Balay    Most users should not need to explicitly call this routine, as it
355a7e14dcfSSatish Balay    is used internally within the minimization solvers.
356a7e14dcfSSatish Balay 
357a7e14dcfSSatish Balay    TaoComputeJacobianState() is typically used within minimization
358a7e14dcfSSatish Balay    implementations, so most users would not generally call this routine
359a7e14dcfSSatish Balay    themselves.
360a7e14dcfSSatish Balay 
361a7e14dcfSSatish Balay    Level: developer
362a7e14dcfSSatish Balay 
363a7e14dcfSSatish Balay .seealso: TaoComputeObjective(), TaoComputeObjectiveAndGradient(), TaoSetJacobianStateRoutine(), TaoComputeJacobianDesign(), TaoSetStateDesignIS()
364a7e14dcfSSatish Balay @*/
365ffad9901SBarry Smith PetscErrorCode TaoComputeJacobianState(Tao tao, Vec X, Mat J, Mat Jpre, Mat Jinv)
366a7e14dcfSSatish Balay {
367a7e14dcfSSatish Balay   PetscErrorCode ierr;
36845cf516eSBarry Smith 
369a7e14dcfSSatish Balay   PetscFunctionBegin;
370441846f8SBarry Smith   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
371a7e14dcfSSatish Balay   PetscValidHeaderSpecific(X, VEC_CLASSID,2);
372a7e14dcfSSatish Balay   PetscCheckSameComm(tao,1,X,2);
37387f595a5SBarry Smith   if (!tao->ops->computejacobianstate) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Must call TaoSetJacobianState() first");
374a7e14dcfSSatish Balay   ++tao->njac_state;
3758860a134SJunchao Zhang   ierr = VecLockReadPush(X);CHKERRQ(ierr);
3760ebee16dSLisandro Dalcin   ierr = PetscLogEventBegin(TAO_JacobianEval,tao,X,J,Jpre);CHKERRQ(ierr);
377441846f8SBarry Smith   PetscStackPush("Tao user Jacobian(state) function");
378ffad9901SBarry Smith   ierr = (*tao->ops->computejacobianstate)(tao,X,J,Jpre,Jinv,tao->user_jac_stateP);CHKERRQ(ierr);
379a7e14dcfSSatish Balay   PetscStackPop;
3800ebee16dSLisandro Dalcin   ierr = PetscLogEventEnd(TAO_JacobianEval,tao,X,J,Jpre);CHKERRQ(ierr);
3818860a134SJunchao Zhang   ierr = VecLockReadPop(X);CHKERRQ(ierr);
382a7e14dcfSSatish Balay   PetscFunctionReturn(0);
383a7e14dcfSSatish Balay }
384a7e14dcfSSatish Balay 
385a7e14dcfSSatish Balay /*@C
386a7e14dcfSSatish Balay    TaoComputeJacobianDesign - Computes the Jacobian matrix that has been
387a7e14dcfSSatish Balay    set with TaoSetJacobianDesignRoutine().
388a7e14dcfSSatish Balay 
389441846f8SBarry Smith    Collective on Tao
390a7e14dcfSSatish Balay 
391a7e14dcfSSatish Balay    Input Parameters:
392f4c1ad5cSStefano Zampini +  tao - the Tao solver context
393f4c1ad5cSStefano Zampini -  X   - input vector
394a7e14dcfSSatish Balay 
395a7e14dcfSSatish Balay    Output Parameters:
396f4c1ad5cSStefano Zampini .  J - Jacobian matrix
397a7e14dcfSSatish Balay 
398a7e14dcfSSatish Balay    Notes:
399a7e14dcfSSatish Balay    Most users should not need to explicitly call this routine, as it
400a7e14dcfSSatish Balay    is used internally within the minimization solvers.
401a7e14dcfSSatish Balay 
402a7e14dcfSSatish Balay    TaoComputeJacobianDesign() is typically used within minimization
403a7e14dcfSSatish Balay    implementations, so most users would not generally call this routine
404a7e14dcfSSatish Balay    themselves.
405a7e14dcfSSatish Balay 
406a7e14dcfSSatish Balay    Level: developer
407a7e14dcfSSatish Balay 
408a7e14dcfSSatish Balay .seealso:  TaoComputeObjective(), TaoComputeObjectiveAndGradient(), TaoSetJacobianDesignRoutine(), TaoComputeJacobianDesign(), TaoSetStateDesignIS()
409a7e14dcfSSatish Balay @*/
41094ab13aaSBarry Smith PetscErrorCode TaoComputeJacobianDesign(Tao tao, Vec X, Mat J)
411a7e14dcfSSatish Balay {
412a7e14dcfSSatish Balay   PetscErrorCode ierr;
41387f595a5SBarry Smith 
414a7e14dcfSSatish Balay   PetscFunctionBegin;
415441846f8SBarry Smith   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
416a7e14dcfSSatish Balay   PetscValidHeaderSpecific(X, VEC_CLASSID,2);
417a7e14dcfSSatish Balay   PetscCheckSameComm(tao,1,X,2);
41887f595a5SBarry Smith   if (!tao->ops->computejacobiandesign) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Must call TaoSetJacobianDesign() first");
419a7e14dcfSSatish Balay   ++tao->njac_design;
4208860a134SJunchao Zhang   ierr = VecLockReadPush(X);CHKERRQ(ierr);
4210ebee16dSLisandro Dalcin   ierr = PetscLogEventBegin(TAO_JacobianEval,tao,X,J,NULL);CHKERRQ(ierr);
422441846f8SBarry Smith   PetscStackPush("Tao user Jacobian(design) function");
423a7e14dcfSSatish Balay   ierr = (*tao->ops->computejacobiandesign)(tao,X,J,tao->user_jac_designP);CHKERRQ(ierr);
424a7e14dcfSSatish Balay   PetscStackPop;
4250ebee16dSLisandro Dalcin   ierr = PetscLogEventEnd(TAO_JacobianEval,tao,X,J,NULL);CHKERRQ(ierr);
4268860a134SJunchao Zhang   ierr = VecLockReadPop(X);CHKERRQ(ierr);
427a7e14dcfSSatish Balay   PetscFunctionReturn(0);
428a7e14dcfSSatish Balay }
429a7e14dcfSSatish Balay 
430a7e14dcfSSatish Balay /*@C
431a7e14dcfSSatish Balay    TaoSetJacobianRoutine - Sets the function to compute the Jacobian as well as the location to store the matrix.
432a7e14dcfSSatish Balay 
433441846f8SBarry Smith    Logically collective on Tao
434a7e14dcfSSatish Balay 
435a7e14dcfSSatish Balay    Input Parameters:
436441846f8SBarry Smith +  tao  - the Tao context
437a7e14dcfSSatish Balay .  J    - Matrix used for the jacobian
438a7e14dcfSSatish Balay .  Jpre - Matrix that will be used operated on by preconditioner, can be same as J
439f4c1ad5cSStefano Zampini .  func - Jacobian evaluation routine
440a7e14dcfSSatish Balay -  ctx  - [optional] user-defined context for private data for the
4416c23d075SBarry Smith           Jacobian evaluation routine (may be NULL)
442a7e14dcfSSatish Balay 
443f4c1ad5cSStefano Zampini    Calling sequence of func:
444f4c1ad5cSStefano Zampini $    func(Tao tao,Vec x,Mat J,Mat Jpre,void *ctx);
445a7e14dcfSSatish Balay 
446441846f8SBarry Smith +  tao  - the Tao  context
447a7e14dcfSSatish Balay .  x    - input vector
448a7e14dcfSSatish Balay .  J    - Jacobian matrix
449f4c1ad5cSStefano Zampini .  Jpre - preconditioning matrix, usually the same as J
450a7e14dcfSSatish Balay -  ctx  - [optional] user-defined Jacobian context
451a7e14dcfSSatish Balay 
452a7e14dcfSSatish Balay    Level: intermediate
453a7e14dcfSSatish Balay @*/
454ffad9901SBarry Smith PetscErrorCode TaoSetJacobianRoutine(Tao tao, Mat J, Mat Jpre, PetscErrorCode (*func)(Tao, Vec, Mat, Mat, void*), void *ctx)
455a7e14dcfSSatish Balay {
456a7e14dcfSSatish Balay   PetscErrorCode ierr;
457f4c1ad5cSStefano Zampini 
458a7e14dcfSSatish Balay   PetscFunctionBegin;
459441846f8SBarry Smith   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
460a7e14dcfSSatish Balay   if (J) {
461a7e14dcfSSatish Balay     PetscValidHeaderSpecific(J,MAT_CLASSID,2);
462a7e14dcfSSatish Balay     PetscCheckSameComm(tao,1,J,2);
463a7e14dcfSSatish Balay   }
464a7e14dcfSSatish Balay   if (Jpre) {
465a7e14dcfSSatish Balay     PetscValidHeaderSpecific(Jpre,MAT_CLASSID,3);
466a7e14dcfSSatish Balay     PetscCheckSameComm(tao,1,Jpre,3);
467a7e14dcfSSatish Balay   }
468a7e14dcfSSatish Balay   if (ctx) {
469a7e14dcfSSatish Balay     tao->user_jacP = ctx;
470a7e14dcfSSatish Balay   }
471a7e14dcfSSatish Balay   if (func) {
472a7e14dcfSSatish Balay     tao->ops->computejacobian = func;
473a7e14dcfSSatish Balay   }
474a7e14dcfSSatish Balay   if (J) {
475a7e14dcfSSatish Balay     ierr = PetscObjectReference((PetscObject)J);CHKERRQ(ierr);
47645cf516eSBarry Smith     ierr = MatDestroy(&tao->jacobian);CHKERRQ(ierr);
477a7e14dcfSSatish Balay     tao->jacobian = J;
478a7e14dcfSSatish Balay   }
479a7e14dcfSSatish Balay   if (Jpre) {
480a7e14dcfSSatish Balay     ierr = PetscObjectReference((PetscObject)Jpre);CHKERRQ(ierr);
48145cf516eSBarry Smith     ierr = MatDestroy(&tao->jacobian_pre);CHKERRQ(ierr);
482a7e14dcfSSatish Balay     tao->jacobian_pre=Jpre;
483a7e14dcfSSatish Balay   }
484a7e14dcfSSatish Balay   PetscFunctionReturn(0);
485a7e14dcfSSatish Balay }
486a7e14dcfSSatish Balay 
487a7e14dcfSSatish Balay /*@C
4884ffbe8acSAlp Dener    TaoSetJacobianResidualRoutine - Sets the function to compute the least-squares residual Jacobian as well as the
4894a48860cSAlp Dener    location to store the matrix.
4904a48860cSAlp Dener 
4914a48860cSAlp Dener    Logically collective on Tao
4924a48860cSAlp Dener 
4934a48860cSAlp Dener    Input Parameters:
4944a48860cSAlp Dener +  tao  - the Tao context
4954a48860cSAlp Dener .  J    - Matrix used for the jacobian
4964a48860cSAlp Dener .  Jpre - Matrix that will be used operated on by preconditioner, can be same as J
4974a48860cSAlp Dener .  func - Jacobian evaluation routine
4984a48860cSAlp Dener -  ctx  - [optional] user-defined context for private data for the
4994a48860cSAlp Dener           Jacobian evaluation routine (may be NULL)
5004a48860cSAlp Dener 
5014a48860cSAlp Dener    Calling sequence of func:
5024a48860cSAlp Dener $    func(Tao tao,Vec x,Mat J,Mat Jpre,void *ctx);
5034a48860cSAlp Dener 
5044a48860cSAlp Dener +  tao  - the Tao  context
5054a48860cSAlp Dener .  x    - input vector
5064a48860cSAlp Dener .  J    - Jacobian matrix
5074a48860cSAlp Dener .  Jpre - preconditioning matrix, usually the same as J
5084a48860cSAlp Dener -  ctx  - [optional] user-defined Jacobian context
5094a48860cSAlp Dener 
5104a48860cSAlp Dener    Level: intermediate
5114a48860cSAlp Dener @*/
5124ffbe8acSAlp Dener PetscErrorCode TaoSetJacobianResidualRoutine(Tao tao, Mat J, Mat Jpre, PetscErrorCode (*func)(Tao, Vec, Mat, Mat, void*), void *ctx)
5134a48860cSAlp Dener {
5144a48860cSAlp Dener   PetscErrorCode ierr;
5154a48860cSAlp Dener 
5164a48860cSAlp Dener   PetscFunctionBegin;
5174a48860cSAlp Dener   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
5184a48860cSAlp Dener   if (J) {
5194a48860cSAlp Dener     PetscValidHeaderSpecific(J,MAT_CLASSID,2);
5204a48860cSAlp Dener     PetscCheckSameComm(tao,1,J,2);
5214a48860cSAlp Dener   }
5224a48860cSAlp Dener   if (Jpre) {
5234a48860cSAlp Dener     PetscValidHeaderSpecific(Jpre,MAT_CLASSID,3);
5244a48860cSAlp Dener     PetscCheckSameComm(tao,1,Jpre,3);
5254a48860cSAlp Dener   }
5264a48860cSAlp Dener   if (ctx) {
5274a48860cSAlp Dener     tao->user_lsjacP = ctx;
5284a48860cSAlp Dener   }
5294a48860cSAlp Dener   if (func) {
5304a48860cSAlp Dener     tao->ops->computeresidualjacobian = func;
5314a48860cSAlp Dener   }
5324a48860cSAlp Dener   if (J) {
5334a48860cSAlp Dener     ierr = PetscObjectReference((PetscObject)J);CHKERRQ(ierr);
5344a48860cSAlp Dener     ierr = MatDestroy(&tao->ls_jac);CHKERRQ(ierr);
5354a48860cSAlp Dener     tao->ls_jac = J;
5364a48860cSAlp Dener   }
5374a48860cSAlp Dener   if (Jpre) {
5384a48860cSAlp Dener     ierr = PetscObjectReference((PetscObject)Jpre);CHKERRQ(ierr);
5394a48860cSAlp Dener     ierr = MatDestroy(&tao->ls_jac_pre);CHKERRQ(ierr);
5404a48860cSAlp Dener     tao->ls_jac_pre=Jpre;
5414a48860cSAlp Dener   }
5424a48860cSAlp Dener   PetscFunctionReturn(0);
5434a48860cSAlp Dener }
5444a48860cSAlp Dener 
5454a48860cSAlp Dener /*@C
546a7e14dcfSSatish Balay    TaoSetJacobianStateRoutine - Sets the function to compute the Jacobian
547a7e14dcfSSatish Balay    (and its inverse) of the constraint function with respect to the state variables.
548a7e14dcfSSatish Balay    Used only for pde-constrained optimization.
549a7e14dcfSSatish Balay 
550441846f8SBarry Smith    Logically collective on Tao
551a7e14dcfSSatish Balay 
552a7e14dcfSSatish Balay    Input Parameters:
553441846f8SBarry Smith +  tao  - the Tao context
554a7e14dcfSSatish Balay .  J    - Matrix used for the jacobian
5556c23d075SBarry Smith .  Jpre - Matrix that will be used operated on by PETSc preconditioner, can be same as J.  Only used if Jinv is NULL
5566c23d075SBarry 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.
557f4c1ad5cSStefano Zampini .  func - Jacobian evaluation routine
558a7e14dcfSSatish Balay -  ctx  - [optional] user-defined context for private data for the
5596c23d075SBarry Smith           Jacobian evaluation routine (may be NULL)
560a7e14dcfSSatish Balay 
561f4c1ad5cSStefano Zampini    Calling sequence of func:
562f4c1ad5cSStefano Zampini $    func(Tao tao,Vec x,Mat J,Mat Jpre,Mat Jinv,void *ctx);
563a7e14dcfSSatish Balay 
564441846f8SBarry Smith +  tao  - the Tao  context
565a7e14dcfSSatish Balay .  x    - input vector
566a7e14dcfSSatish Balay .  J    - Jacobian matrix
567a7e14dcfSSatish Balay .  Jpre - preconditioner matrix, usually the same as J
568a7e14dcfSSatish Balay .  Jinv - inverse of J
569a7e14dcfSSatish Balay -  ctx  - [optional] user-defined Jacobian context
570a7e14dcfSSatish Balay 
571a7e14dcfSSatish Balay    Level: intermediate
572f4c1ad5cSStefano Zampini .seealso: TaoComputeJacobianState(), TaoSetJacobianDesignRoutine(), TaoSetStateDesignIS()
573a7e14dcfSSatish Balay @*/
574ffad9901SBarry Smith PetscErrorCode TaoSetJacobianStateRoutine(Tao tao, Mat J, Mat Jpre, Mat Jinv, PetscErrorCode (*func)(Tao, Vec, Mat, Mat, Mat, void*), void *ctx)
575a7e14dcfSSatish Balay {
576a7e14dcfSSatish Balay   PetscErrorCode ierr;
577f4c1ad5cSStefano Zampini 
578a7e14dcfSSatish Balay   PetscFunctionBegin;
579441846f8SBarry Smith   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
580a7e14dcfSSatish Balay   if (J) {
581a7e14dcfSSatish Balay     PetscValidHeaderSpecific(J,MAT_CLASSID,2);
582a7e14dcfSSatish Balay     PetscCheckSameComm(tao,1,J,2);
583a7e14dcfSSatish Balay   }
584a7e14dcfSSatish Balay   if (Jpre) {
585a7e14dcfSSatish Balay     PetscValidHeaderSpecific(Jpre,MAT_CLASSID,3);
586a7e14dcfSSatish Balay     PetscCheckSameComm(tao,1,Jpre,3);
587a7e14dcfSSatish Balay   }
588a7e14dcfSSatish Balay   if (Jinv) {
589a7e14dcfSSatish Balay     PetscValidHeaderSpecific(Jinv,MAT_CLASSID,4);
590a7e14dcfSSatish Balay     PetscCheckSameComm(tao,1,Jinv,4);
591a7e14dcfSSatish Balay   }
592a7e14dcfSSatish Balay   if (ctx) {
593a7e14dcfSSatish Balay     tao->user_jac_stateP = ctx;
594a7e14dcfSSatish Balay   }
595a7e14dcfSSatish Balay   if (func) {
596a7e14dcfSSatish Balay     tao->ops->computejacobianstate = func;
597a7e14dcfSSatish Balay   }
598a7e14dcfSSatish Balay   if (J) {
599a7e14dcfSSatish Balay     ierr = PetscObjectReference((PetscObject)J);CHKERRQ(ierr);
60045cf516eSBarry Smith     ierr = MatDestroy(&tao->jacobian_state);CHKERRQ(ierr);
601a7e14dcfSSatish Balay     tao->jacobian_state = J;
602a7e14dcfSSatish Balay   }
603a7e14dcfSSatish Balay   if (Jpre) {
604a7e14dcfSSatish Balay     ierr = PetscObjectReference((PetscObject)Jpre);CHKERRQ(ierr);
60545cf516eSBarry Smith     ierr = MatDestroy(&tao->jacobian_state_pre);CHKERRQ(ierr);
606a7e14dcfSSatish Balay     tao->jacobian_state_pre=Jpre;
607a7e14dcfSSatish Balay   }
608a7e14dcfSSatish Balay   if (Jinv) {
609a7e14dcfSSatish Balay     ierr = PetscObjectReference((PetscObject)Jinv);CHKERRQ(ierr);
61045cf516eSBarry Smith     ierr = MatDestroy(&tao->jacobian_state_inv);CHKERRQ(ierr);
611a7e14dcfSSatish Balay     tao->jacobian_state_inv=Jinv;
612a7e14dcfSSatish Balay   }
613a7e14dcfSSatish Balay   PetscFunctionReturn(0);
614a7e14dcfSSatish Balay }
615a7e14dcfSSatish Balay 
616a7e14dcfSSatish Balay /*@C
617a7e14dcfSSatish Balay    TaoSetJacobianDesignRoutine - Sets the function to compute the Jacobian of
618a7e14dcfSSatish Balay    the constraint function with respect to the design variables.  Used only for
619a7e14dcfSSatish Balay    pde-constrained optimization.
620a7e14dcfSSatish Balay 
621441846f8SBarry Smith    Logically collective on Tao
622a7e14dcfSSatish Balay 
623a7e14dcfSSatish Balay    Input Parameters:
624441846f8SBarry Smith +  tao  - the Tao context
625a7e14dcfSSatish Balay .  J    - Matrix used for the jacobian
626f4c1ad5cSStefano Zampini .  func - Jacobian evaluation routine
627a7e14dcfSSatish Balay -  ctx  - [optional] user-defined context for private data for the
6286c23d075SBarry Smith           Jacobian evaluation routine (may be NULL)
629a7e14dcfSSatish Balay 
630f4c1ad5cSStefano Zampini    Calling sequence of func:
631f4c1ad5cSStefano Zampini $    func(Tao tao,Vec x,Mat J,void *ctx);
632a7e14dcfSSatish Balay 
633441846f8SBarry Smith +  tao - the Tao  context
634a7e14dcfSSatish Balay .  x   - input vector
635a7e14dcfSSatish Balay .  J   - Jacobian matrix
636a7e14dcfSSatish Balay -  ctx - [optional] user-defined Jacobian context
637a7e14dcfSSatish Balay 
638a7e14dcfSSatish Balay    Level: intermediate
639f4c1ad5cSStefano Zampini 
640a7e14dcfSSatish Balay .seealso: TaoComputeJacobianDesign(), TaoSetJacobianStateRoutine(), TaoSetStateDesignIS()
641a7e14dcfSSatish Balay @*/
64294ab13aaSBarry Smith PetscErrorCode TaoSetJacobianDesignRoutine(Tao tao, Mat J, PetscErrorCode (*func)(Tao, Vec, Mat, void*), void *ctx)
643a7e14dcfSSatish Balay {
644a7e14dcfSSatish Balay   PetscErrorCode ierr;
64545cf516eSBarry Smith 
646a7e14dcfSSatish Balay   PetscFunctionBegin;
647441846f8SBarry Smith   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
648a7e14dcfSSatish Balay   if (J) {
649a7e14dcfSSatish Balay     PetscValidHeaderSpecific(J,MAT_CLASSID,2);
650a7e14dcfSSatish Balay     PetscCheckSameComm(tao,1,J,2);
651a7e14dcfSSatish Balay   }
652a7e14dcfSSatish Balay   if (ctx) {
653a7e14dcfSSatish Balay     tao->user_jac_designP = ctx;
654a7e14dcfSSatish Balay   }
655a7e14dcfSSatish Balay   if (func) {
656a7e14dcfSSatish Balay     tao->ops->computejacobiandesign = func;
657a7e14dcfSSatish Balay   }
658a7e14dcfSSatish Balay   if (J) {
659a7e14dcfSSatish Balay     ierr = PetscObjectReference((PetscObject)J);CHKERRQ(ierr);
66045cf516eSBarry Smith     ierr = MatDestroy(&tao->jacobian_design);CHKERRQ(ierr);
661a7e14dcfSSatish Balay     tao->jacobian_design = J;
662a7e14dcfSSatish Balay   }
663a7e14dcfSSatish Balay   PetscFunctionReturn(0);
664a7e14dcfSSatish Balay }
665a7e14dcfSSatish Balay 
666a7e14dcfSSatish Balay /*@
667441846f8SBarry Smith    TaoSetStateDesignIS - Indicate to the Tao which variables in the
668a7e14dcfSSatish Balay    solution vector are state variables and which are design.  Only applies to
669a7e14dcfSSatish Balay    pde-constrained optimization.
670a7e14dcfSSatish Balay 
671441846f8SBarry Smith    Logically Collective on Tao
672a7e14dcfSSatish Balay 
673a7e14dcfSSatish Balay    Input Parameters:
674441846f8SBarry Smith +  tao  - The Tao context
675a7e14dcfSSatish Balay .  s_is - the index set corresponding to the state variables
676a7e14dcfSSatish Balay -  d_is - the index set corresponding to the design variables
677a7e14dcfSSatish Balay 
678a7e14dcfSSatish Balay    Level: intermediate
679a7e14dcfSSatish Balay 
680a7e14dcfSSatish Balay .seealso: TaoSetJacobianStateRoutine(), TaoSetJacobianDesignRoutine()
681a7e14dcfSSatish Balay @*/
682441846f8SBarry Smith PetscErrorCode TaoSetStateDesignIS(Tao tao, IS s_is, IS d_is)
683a7e14dcfSSatish Balay {
684a7e14dcfSSatish Balay   PetscErrorCode ierr;
68545cf516eSBarry Smith 
68645cf516eSBarry Smith   PetscFunctionBegin;
68745cf516eSBarry Smith   ierr = PetscObjectReference((PetscObject)s_is);CHKERRQ(ierr);
68845cf516eSBarry Smith   ierr = ISDestroy(&tao->state_is);CHKERRQ(ierr);
689a7e14dcfSSatish Balay   tao->state_is = s_is;
69045cf516eSBarry Smith   ierr = PetscObjectReference((PetscObject)(d_is));CHKERRQ(ierr);
69145cf516eSBarry Smith   ierr = ISDestroy(&tao->design_is);CHKERRQ(ierr);
692a7e14dcfSSatish Balay   tao->design_is = d_is;
693a7e14dcfSSatish Balay   PetscFunctionReturn(0);
694a7e14dcfSSatish Balay }
695a7e14dcfSSatish Balay 
696a7e14dcfSSatish Balay /*@C
697a7e14dcfSSatish Balay    TaoComputeJacobianEquality - Computes the Jacobian matrix that has been
698a7e14dcfSSatish Balay    set with TaoSetJacobianEqualityRoutine().
699a7e14dcfSSatish Balay 
700441846f8SBarry Smith    Collective on Tao
701a7e14dcfSSatish Balay 
702a7e14dcfSSatish Balay    Input Parameters:
703f4c1ad5cSStefano Zampini +  tao - the Tao solver context
704f4c1ad5cSStefano Zampini -  X   - input vector
705a7e14dcfSSatish Balay 
706a7e14dcfSSatish Balay    Output Parameters:
707f4c1ad5cSStefano Zampini +  J    - Jacobian matrix
708f4c1ad5cSStefano Zampini -  Jpre - Preconditioning matrix
709a7e14dcfSSatish Balay 
710a7e14dcfSSatish Balay    Notes:
711a7e14dcfSSatish Balay    Most users should not need to explicitly call this routine, as it
712a7e14dcfSSatish Balay    is used internally within the minimization solvers.
713a7e14dcfSSatish Balay 
714a7e14dcfSSatish Balay    Level: developer
715a7e14dcfSSatish Balay 
716a7e14dcfSSatish Balay .seealso:  TaoComputeObjective(), TaoComputeObjectiveAndGradient(), TaoSetJacobianStateRoutine(), TaoComputeJacobianDesign(), TaoSetStateDesignIS()
717a7e14dcfSSatish Balay @*/
718ffad9901SBarry Smith PetscErrorCode TaoComputeJacobianEquality(Tao tao, Vec X, Mat J, Mat Jpre)
719a7e14dcfSSatish Balay {
720a7e14dcfSSatish Balay   PetscErrorCode ierr;
72145cf516eSBarry Smith 
722a7e14dcfSSatish Balay   PetscFunctionBegin;
723441846f8SBarry Smith   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
724a7e14dcfSSatish Balay   PetscValidHeaderSpecific(X, VEC_CLASSID,2);
725a7e14dcfSSatish Balay   PetscCheckSameComm(tao,1,X,2);
72687f595a5SBarry Smith   if (!tao->ops->computejacobianequality) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Must call TaoSetJacobianEquality() first");
727a7e14dcfSSatish Balay   ++tao->njac_equality;
7288860a134SJunchao Zhang   ierr = VecLockReadPush(X);CHKERRQ(ierr);
7290ebee16dSLisandro Dalcin   ierr = PetscLogEventBegin(TAO_JacobianEval,tao,X,J,Jpre);CHKERRQ(ierr);
730441846f8SBarry Smith   PetscStackPush("Tao user Jacobian(equality) function");
731ffad9901SBarry Smith   ierr = (*tao->ops->computejacobianequality)(tao,X,J,Jpre,tao->user_jac_equalityP);CHKERRQ(ierr);
732a7e14dcfSSatish Balay   PetscStackPop;
7330ebee16dSLisandro Dalcin   ierr = PetscLogEventEnd(TAO_JacobianEval,tao,X,J,Jpre);CHKERRQ(ierr);
7348860a134SJunchao Zhang   ierr = VecLockReadPop(X);CHKERRQ(ierr);
735a7e14dcfSSatish Balay   PetscFunctionReturn(0);
736a7e14dcfSSatish Balay }
737a7e14dcfSSatish Balay 
738a7e14dcfSSatish Balay /*@C
739a7e14dcfSSatish Balay    TaoComputeJacobianInequality - Computes the Jacobian matrix that has been
740a7e14dcfSSatish Balay    set with TaoSetJacobianInequalityRoutine().
741a7e14dcfSSatish Balay 
742441846f8SBarry Smith    Collective on Tao
743a7e14dcfSSatish Balay 
744a7e14dcfSSatish Balay    Input Parameters:
745f4c1ad5cSStefano Zampini +  tao - the Tao solver context
746f4c1ad5cSStefano Zampini -  X   - input vector
747a7e14dcfSSatish Balay 
748a7e14dcfSSatish Balay    Output Parameters:
749f4c1ad5cSStefano Zampini +  J    - Jacobian matrix
750f4c1ad5cSStefano Zampini -  Jpre - Preconditioning matrix
751a7e14dcfSSatish Balay 
752a7e14dcfSSatish Balay    Notes:
753a7e14dcfSSatish Balay    Most users should not need to explicitly call this routine, as it
754a7e14dcfSSatish Balay    is used internally within the minimization solvers.
755a7e14dcfSSatish Balay 
756a7e14dcfSSatish Balay    Level: developer
757a7e14dcfSSatish Balay 
758a7e14dcfSSatish Balay .seealso:  TaoComputeObjective(), TaoComputeObjectiveAndGradient(), TaoSetJacobianStateRoutine(), TaoComputeJacobianDesign(), TaoSetStateDesignIS()
759a7e14dcfSSatish Balay @*/
760ffad9901SBarry Smith PetscErrorCode TaoComputeJacobianInequality(Tao tao, Vec X, Mat J, Mat Jpre)
761a7e14dcfSSatish Balay {
762a7e14dcfSSatish Balay   PetscErrorCode ierr;
76387f595a5SBarry Smith 
764a7e14dcfSSatish Balay   PetscFunctionBegin;
765441846f8SBarry Smith   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
766a7e14dcfSSatish Balay   PetscValidHeaderSpecific(X, VEC_CLASSID,2);
767a7e14dcfSSatish Balay   PetscCheckSameComm(tao,1,X,2);
76887f595a5SBarry Smith   if (!tao->ops->computejacobianinequality) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Must call TaoSetJacobianInequality() first");
769a7e14dcfSSatish Balay   ++tao->njac_inequality;
7708860a134SJunchao Zhang   ierr = VecLockReadPush(X);CHKERRQ(ierr);
7710ebee16dSLisandro Dalcin   ierr = PetscLogEventBegin(TAO_JacobianEval,tao,X,J,Jpre);CHKERRQ(ierr);
772441846f8SBarry Smith   PetscStackPush("Tao user Jacobian(inequality) function");
773ffad9901SBarry Smith   ierr = (*tao->ops->computejacobianinequality)(tao,X,J,Jpre,tao->user_jac_inequalityP);CHKERRQ(ierr);
774a7e14dcfSSatish Balay   PetscStackPop;
7750ebee16dSLisandro Dalcin   ierr = PetscLogEventEnd(TAO_JacobianEval,tao,X,J,Jpre);CHKERRQ(ierr);
7768860a134SJunchao Zhang   ierr = VecLockReadPop(X);CHKERRQ(ierr);
777a7e14dcfSSatish Balay   PetscFunctionReturn(0);
778a7e14dcfSSatish Balay }
779a7e14dcfSSatish Balay 
780a7e14dcfSSatish Balay /*@C
781a7e14dcfSSatish Balay    TaoSetJacobianEqualityRoutine - Sets the function to compute the Jacobian
782a7e14dcfSSatish Balay    (and its inverse) of the constraint function with respect to the equality variables.
783a7e14dcfSSatish Balay    Used only for pde-constrained optimization.
784a7e14dcfSSatish Balay 
785441846f8SBarry Smith    Logically collective on Tao
786a7e14dcfSSatish Balay 
787a7e14dcfSSatish Balay    Input Parameters:
788441846f8SBarry Smith +  tao  - the Tao context
789a7e14dcfSSatish Balay .  J    - Matrix used for the jacobian
790a7e14dcfSSatish Balay .  Jpre - Matrix that will be used operated on by PETSc preconditioner, can be same as J.
791f4c1ad5cSStefano Zampini .  func - Jacobian evaluation routine
792a7e14dcfSSatish Balay -  ctx  - [optional] user-defined context for private data for the
7936c23d075SBarry Smith           Jacobian evaluation routine (may be NULL)
794a7e14dcfSSatish Balay 
795f4c1ad5cSStefano Zampini    Calling sequence of func:
796f4c1ad5cSStefano Zampini $    func(Tao tao,Vec x,Mat J,Mat Jpre,void *ctx);
797a7e14dcfSSatish Balay 
798441846f8SBarry Smith +  tao  - the Tao  context
799a7e14dcfSSatish Balay .  x    - input vector
800a7e14dcfSSatish Balay .  J    - Jacobian matrix
801a7e14dcfSSatish Balay .  Jpre - preconditioner matrix, usually the same as J
802a7e14dcfSSatish Balay -  ctx  - [optional] user-defined Jacobian context
803a7e14dcfSSatish Balay 
804a7e14dcfSSatish Balay    Level: intermediate
805f4c1ad5cSStefano Zampini 
806f4c1ad5cSStefano Zampini .seealso: TaoComputeJacobianEquality(), TaoSetJacobianDesignRoutine(), TaoSetEqualityDesignIS()
807a7e14dcfSSatish Balay @*/
808ffad9901SBarry Smith PetscErrorCode TaoSetJacobianEqualityRoutine(Tao tao, Mat J, Mat Jpre, PetscErrorCode (*func)(Tao, Vec, Mat, Mat,void*), void *ctx)
809a7e14dcfSSatish Balay {
810a7e14dcfSSatish Balay   PetscErrorCode ierr;
81145cf516eSBarry Smith 
812a7e14dcfSSatish Balay   PetscFunctionBegin;
813441846f8SBarry Smith   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
814a7e14dcfSSatish Balay   if (J) {
815a7e14dcfSSatish Balay     PetscValidHeaderSpecific(J,MAT_CLASSID,2);
816a7e14dcfSSatish Balay     PetscCheckSameComm(tao,1,J,2);
817a7e14dcfSSatish Balay   }
818a7e14dcfSSatish Balay   if (Jpre) {
819a7e14dcfSSatish Balay     PetscValidHeaderSpecific(Jpre,MAT_CLASSID,3);
820a7e14dcfSSatish Balay     PetscCheckSameComm(tao,1,Jpre,3);
821a7e14dcfSSatish Balay   }
822a7e14dcfSSatish Balay   if (ctx) {
823a7e14dcfSSatish Balay     tao->user_jac_equalityP = ctx;
824a7e14dcfSSatish Balay   }
825a7e14dcfSSatish Balay   if (func) {
826a7e14dcfSSatish Balay     tao->ops->computejacobianequality = func;
827a7e14dcfSSatish Balay   }
828a7e14dcfSSatish Balay   if (J) {
829a7e14dcfSSatish Balay     ierr = PetscObjectReference((PetscObject)J);CHKERRQ(ierr);
83045cf516eSBarry Smith     ierr = MatDestroy(&tao->jacobian_equality);CHKERRQ(ierr);
831a7e14dcfSSatish Balay     tao->jacobian_equality = J;
832a7e14dcfSSatish Balay   }
833a7e14dcfSSatish Balay   if (Jpre) {
834a7e14dcfSSatish Balay     ierr = PetscObjectReference((PetscObject)Jpre);CHKERRQ(ierr);
83545cf516eSBarry Smith     ierr = MatDestroy(&tao->jacobian_equality_pre);CHKERRQ(ierr);
836a7e14dcfSSatish Balay     tao->jacobian_equality_pre=Jpre;
837a7e14dcfSSatish Balay   }
838a7e14dcfSSatish Balay   PetscFunctionReturn(0);
839a7e14dcfSSatish Balay }
840a7e14dcfSSatish Balay 
841a7e14dcfSSatish Balay /*@C
842a7e14dcfSSatish Balay    TaoSetJacobianInequalityRoutine - Sets the function to compute the Jacobian
843a7e14dcfSSatish Balay    (and its inverse) of the constraint function with respect to the inequality variables.
844a7e14dcfSSatish Balay    Used only for pde-constrained optimization.
845a7e14dcfSSatish Balay 
846441846f8SBarry Smith    Logically collective on Tao
847a7e14dcfSSatish Balay 
848a7e14dcfSSatish Balay    Input Parameters:
849441846f8SBarry Smith +  tao  - the Tao context
850a7e14dcfSSatish Balay .  J    - Matrix used for the jacobian
851a7e14dcfSSatish Balay .  Jpre - Matrix that will be used operated on by PETSc preconditioner, can be same as J.
852f4c1ad5cSStefano Zampini .  func - Jacobian evaluation routine
853a7e14dcfSSatish Balay -  ctx  - [optional] user-defined context for private data for the
8546c23d075SBarry Smith           Jacobian evaluation routine (may be NULL)
855a7e14dcfSSatish Balay 
856f4c1ad5cSStefano Zampini    Calling sequence of func:
857f4c1ad5cSStefano Zampini $    func(Tao tao,Vec x,Mat J,Mat Jpre,void *ctx);
858a7e14dcfSSatish Balay 
859441846f8SBarry Smith +  tao  - the Tao  context
860a7e14dcfSSatish Balay .  x    - input vector
861a7e14dcfSSatish Balay .  J    - Jacobian matrix
862a7e14dcfSSatish Balay .  Jpre - preconditioner matrix, usually the same as J
863a7e14dcfSSatish Balay -  ctx  - [optional] user-defined Jacobian context
864a7e14dcfSSatish Balay 
865a7e14dcfSSatish Balay    Level: intermediate
866f4c1ad5cSStefano Zampini 
867f4c1ad5cSStefano Zampini .seealso: TaoComputeJacobianInequality(), TaoSetJacobianDesignRoutine(), TaoSetInequalityDesignIS()
868a7e14dcfSSatish Balay @*/
869ffad9901SBarry Smith PetscErrorCode TaoSetJacobianInequalityRoutine(Tao tao, Mat J, Mat Jpre, PetscErrorCode (*func)(Tao, Vec, Mat, Mat,void*), void *ctx)
870a7e14dcfSSatish Balay {
871a7e14dcfSSatish Balay   PetscErrorCode ierr;
872f4c1ad5cSStefano Zampini 
873a7e14dcfSSatish Balay   PetscFunctionBegin;
874441846f8SBarry Smith   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
875a7e14dcfSSatish Balay   if (J) {
876a7e14dcfSSatish Balay     PetscValidHeaderSpecific(J,MAT_CLASSID,2);
877a7e14dcfSSatish Balay     PetscCheckSameComm(tao,1,J,2);
878a7e14dcfSSatish Balay   }
879a7e14dcfSSatish Balay   if (Jpre) {
880a7e14dcfSSatish Balay     PetscValidHeaderSpecific(Jpre,MAT_CLASSID,3);
881a7e14dcfSSatish Balay     PetscCheckSameComm(tao,1,Jpre,3);
882a7e14dcfSSatish Balay   }
883a7e14dcfSSatish Balay   if (ctx) {
884a7e14dcfSSatish Balay     tao->user_jac_inequalityP = ctx;
885a7e14dcfSSatish Balay   }
886a7e14dcfSSatish Balay   if (func) {
887a7e14dcfSSatish Balay     tao->ops->computejacobianinequality = func;
888a7e14dcfSSatish Balay   }
889a7e14dcfSSatish Balay   if (J) {
890a7e14dcfSSatish Balay     ierr = PetscObjectReference((PetscObject)J);CHKERRQ(ierr);
89145cf516eSBarry Smith     ierr = MatDestroy(&tao->jacobian_inequality);CHKERRQ(ierr);
892a7e14dcfSSatish Balay     tao->jacobian_inequality = J;
893a7e14dcfSSatish Balay   }
894a7e14dcfSSatish Balay   if (Jpre) {
895a7e14dcfSSatish Balay     ierr = PetscObjectReference((PetscObject)Jpre);CHKERRQ(ierr);
89645cf516eSBarry Smith     ierr = MatDestroy(&tao->jacobian_inequality_pre);CHKERRQ(ierr);
897a7e14dcfSSatish Balay     tao->jacobian_inequality_pre=Jpre;
898a7e14dcfSSatish Balay   }
899a7e14dcfSSatish Balay   PetscFunctionReturn(0);
900a7e14dcfSSatish Balay }
901