xref: /petsc/src/tao/interface/taosolver_hj.c (revision 3c859ba3a04a72e8efcb87bc7ffc046a6cbab413)
1af0996ceSBarry Smith #include <petsc/private/taoimpl.h> /*I "petsctao.h" I*/
2a7e14dcfSSatish Balay 
3a7e14dcfSSatish Balay /*@C
4a82e8c82SStefano Zampini    TaoSetHessian - Sets the function to compute the Hessian as well as the location to store the matrix.
5a7e14dcfSSatish Balay 
6441846f8SBarry Smith    Logically collective on Tao
7a7e14dcfSSatish Balay 
8a7e14dcfSSatish Balay    Input Parameters:
9441846f8SBarry Smith +  tao  - the Tao context
10a7e14dcfSSatish Balay .  H    - Matrix used for the hessian
11a7e14dcfSSatish Balay .  Hpre - Matrix that will be used operated on by preconditioner, can be same as H
12f4c1ad5cSStefano Zampini .  func - Hessian evaluation routine
13a7e14dcfSSatish Balay -  ctx  - [optional] user-defined context for private data for the
146c23d075SBarry Smith          Hessian evaluation routine (may be NULL)
15a7e14dcfSSatish Balay 
16f4c1ad5cSStefano Zampini    Calling sequence of func:
17f4c1ad5cSStefano Zampini $    func(Tao tao,Vec x,Mat H,Mat Hpre,void *ctx);
18a7e14dcfSSatish Balay 
19441846f8SBarry Smith +  tao  - the Tao  context
20a7e14dcfSSatish Balay .  x    - input vector
21a7e14dcfSSatish Balay .  H    - Hessian matrix
22a7e14dcfSSatish Balay .  Hpre - preconditioner matrix, usually the same as H
23a7e14dcfSSatish Balay -  ctx  - [optional] user-defined Hessian context
24a7e14dcfSSatish Balay 
25a7e14dcfSSatish Balay    Level: beginner
26a82e8c82SStefano Zampini 
27a82e8c82SStefano Zampini .seealso: TaoSetObjective(), TaoSetGradient(), TaoSetObjectiveAndGradient(), TaoGetHessian()
28a7e14dcfSSatish Balay @*/
29a82e8c82SStefano Zampini PetscErrorCode TaoSetHessian(Tao tao, Mat H, Mat Hpre, PetscErrorCode (*func)(Tao, Vec, Mat, Mat, void*), void *ctx)
30a7e14dcfSSatish Balay {
31a7e14dcfSSatish Balay   PetscErrorCode ierr;
3245cf516eSBarry Smith 
33a7e14dcfSSatish Balay   PetscFunctionBegin;
34441846f8SBarry Smith   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
35a7e14dcfSSatish Balay   if (H) {
36a7e14dcfSSatish Balay     PetscValidHeaderSpecific(H,MAT_CLASSID,2);
37a7e14dcfSSatish Balay     PetscCheckSameComm(tao,1,H,2);
38a7e14dcfSSatish Balay   }
39a7e14dcfSSatish Balay   if (Hpre) {
40a7e14dcfSSatish Balay     PetscValidHeaderSpecific(Hpre,MAT_CLASSID,3);
41a7e14dcfSSatish Balay     PetscCheckSameComm(tao,1,Hpre,3);
42a7e14dcfSSatish Balay   }
43a82e8c82SStefano Zampini   if (ctx) tao->user_hessP = ctx;
44a82e8c82SStefano Zampini   if (func) tao->ops->computehessian = func;
45a7e14dcfSSatish Balay   if (H) {
46a7e14dcfSSatish Balay     ierr = PetscObjectReference((PetscObject)H);CHKERRQ(ierr);
4745cf516eSBarry Smith     ierr = MatDestroy(&tao->hessian);CHKERRQ(ierr);
48a7e14dcfSSatish Balay     tao->hessian = H;
49a7e14dcfSSatish Balay   }
50a7e14dcfSSatish Balay   if (Hpre) {
51a7e14dcfSSatish Balay     ierr = PetscObjectReference((PetscObject)Hpre);CHKERRQ(ierr);
5245cf516eSBarry Smith     ierr = MatDestroy(&tao->hessian_pre);CHKERRQ(ierr);
53a7e14dcfSSatish Balay     tao->hessian_pre = Hpre;
54a7e14dcfSSatish Balay   }
55a7e14dcfSSatish Balay   PetscFunctionReturn(0);
56a7e14dcfSSatish Balay }
57a7e14dcfSSatish Balay 
58a82e8c82SStefano Zampini /*@C
59a82e8c82SStefano Zampini    TaoGetHessian - Gets the function to compute the Hessian as well as the location to store the matrix.
60a82e8c82SStefano Zampini 
61a82e8c82SStefano Zampini    Not collective
62a82e8c82SStefano Zampini 
63a82e8c82SStefano Zampini    Input Parameter:
64a82e8c82SStefano Zampini .  tao  - the Tao context
65a82e8c82SStefano Zampini 
66a82e8c82SStefano Zampini    OutputParameters:
67a82e8c82SStefano Zampini +  H    - Matrix used for the hessian
68a82e8c82SStefano Zampini .  Hpre - Matrix that will be used operated on by preconditioner, can be the same as H
69a82e8c82SStefano Zampini .  func - Hessian evaluation routine
70a82e8c82SStefano Zampini -  ctx  - user-defined context for private data for the Hessian evaluation routine
71a82e8c82SStefano Zampini 
72a82e8c82SStefano Zampini    Calling sequence of func:
73a82e8c82SStefano Zampini $    func(Tao tao,Vec x,Mat H,Mat Hpre,void *ctx);
74a82e8c82SStefano Zampini 
75a82e8c82SStefano Zampini +  tao  - the Tao  context
76a82e8c82SStefano Zampini .  x    - input vector
77a82e8c82SStefano Zampini .  H    - Hessian matrix
78a82e8c82SStefano Zampini .  Hpre - preconditioner matrix, usually the same as H
79a82e8c82SStefano Zampini -  ctx  - [optional] user-defined Hessian context
80a82e8c82SStefano Zampini 
81a82e8c82SStefano Zampini    Level: beginner
82a82e8c82SStefano Zampini 
83a82e8c82SStefano Zampini .seealso: TaoGetObjective(), TaoGetGradient(), TaoGetObjectiveAndGradient(), TaoSetHessian()
84a82e8c82SStefano Zampini @*/
85a82e8c82SStefano Zampini PetscErrorCode TaoGetHessian(Tao tao, Mat *H, Mat *Hpre, PetscErrorCode (**func)(Tao, Vec, Mat, Mat, void*), void **ctx)
86a82e8c82SStefano Zampini {
87a82e8c82SStefano Zampini   PetscFunctionBegin;
88a82e8c82SStefano Zampini   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
89a82e8c82SStefano Zampini   if (H) *H = tao->hessian;
90a82e8c82SStefano Zampini   if (Hpre) *Hpre = tao->hessian_pre;
91a82e8c82SStefano Zampini   if (ctx) *ctx = tao->user_hessP;
92a82e8c82SStefano Zampini   if (func) *func = tao->ops->computehessian;
93a82e8c82SStefano Zampini   PetscFunctionReturn(0);
94a82e8c82SStefano Zampini }
95a82e8c82SStefano Zampini 
9609baa881SHong Zhang PetscErrorCode TaoTestHessian(Tao tao)
9709baa881SHong Zhang {
9809baa881SHong Zhang   Mat               A,B,C,D,hessian;
9909baa881SHong Zhang   Vec               x = tao->solution;
10009baa881SHong Zhang   PetscErrorCode    ierr;
10109baa881SHong Zhang   PetscReal         nrm,gnorm;
10209baa881SHong Zhang   PetscReal         threshold = 1.e-5;
10309baa881SHong Zhang   PetscInt          m,n,M,N;
10409baa881SHong Zhang   PetscBool         complete_print = PETSC_FALSE,test = PETSC_FALSE,flg;
105f49d1c87SHong Zhang   PetscViewer       viewer,mviewer;
10609baa881SHong Zhang   MPI_Comm          comm;
10709baa881SHong Zhang   PetscInt          tabs;
10809baa881SHong Zhang   static PetscBool  directionsprinted = PETSC_FALSE;
109f49d1c87SHong Zhang   PetscViewerFormat format;
11009baa881SHong Zhang 
11109baa881SHong Zhang   PetscFunctionBegin;
11209baa881SHong Zhang   ierr = PetscObjectOptionsBegin((PetscObject)tao);CHKERRQ(ierr);
11309baa881SHong Zhang   ierr = PetscOptionsName("-tao_test_hessian","Compare hand-coded and finite difference Hessians","None",&test);CHKERRQ(ierr);
11409baa881SHong Zhang   ierr = PetscOptionsReal("-tao_test_hessian", "Threshold for element difference between hand-coded and finite difference being meaningful","None",threshold,&threshold,NULL);CHKERRQ(ierr);
115f49d1c87SHong 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);
11609baa881SHong Zhang   ierr = PetscOptionsEnd();CHKERRQ(ierr);
11709baa881SHong Zhang   if (!test) PetscFunctionReturn(0);
11809baa881SHong Zhang 
11909baa881SHong Zhang   ierr = PetscObjectGetComm((PetscObject)tao,&comm);CHKERRQ(ierr);
12009baa881SHong Zhang   ierr = PetscViewerASCIIGetStdout(comm,&viewer);CHKERRQ(ierr);
12109baa881SHong Zhang   ierr = PetscViewerASCIIGetTab(viewer, &tabs);CHKERRQ(ierr);
12209baa881SHong Zhang   ierr = PetscViewerASCIISetTab(viewer, ((PetscObject)tao)->tablevel);CHKERRQ(ierr);
12309baa881SHong Zhang   ierr = PetscViewerASCIIPrintf(viewer,"  ---------- Testing Hessian -------------\n");CHKERRQ(ierr);
12409baa881SHong Zhang   if (!complete_print && !directionsprinted) {
12509baa881SHong Zhang     ierr = PetscViewerASCIIPrintf(viewer,"  Run with -tao_test_hessian_view and optionally -tao_test_hessian <threshold> to show difference\n");CHKERRQ(ierr);
12609baa881SHong Zhang     ierr = PetscViewerASCIIPrintf(viewer,"    of hand-coded and finite difference Hessian entries greater than <threshold>.\n");CHKERRQ(ierr);
12709baa881SHong Zhang   }
12809baa881SHong Zhang   if (!directionsprinted) {
12909baa881SHong Zhang     ierr = PetscViewerASCIIPrintf(viewer,"  Testing hand-coded Hessian, if (for double precision runs) ||J - Jfd||_F/||J||_F is\n");CHKERRQ(ierr);
13009baa881SHong Zhang     ierr = PetscViewerASCIIPrintf(viewer,"    O(1.e-8), the hand-coded Hessian is probably correct.\n");CHKERRQ(ierr);
13109baa881SHong Zhang     directionsprinted = PETSC_TRUE;
13209baa881SHong Zhang   }
133f49d1c87SHong Zhang   if (complete_print) {
134f49d1c87SHong Zhang     ierr = PetscViewerPushFormat(mviewer,format);CHKERRQ(ierr);
135f49d1c87SHong Zhang   }
13609baa881SHong Zhang 
13709baa881SHong Zhang   ierr = PetscObjectTypeCompare((PetscObject)tao->hessian,MATMFFD,&flg);CHKERRQ(ierr);
13809baa881SHong Zhang   if (!flg) hessian = tao->hessian;
13909baa881SHong Zhang   else hessian = tao->hessian_pre;
14009baa881SHong Zhang 
14109baa881SHong Zhang   while (hessian) {
142b9e7e5c1SBarry Smith     ierr = PetscObjectBaseTypeCompareAny((PetscObject)hessian,&flg,MATSEQAIJ,MATMPIAIJ,MATSEQDENSE,MATMPIDENSE,MATSEQBAIJ,MATMPIBAIJ,MATSEQSBAIJ,MATMPIBAIJ,"");CHKERRQ(ierr);
14309baa881SHong Zhang     if (flg) {
14409baa881SHong Zhang       A    = hessian;
14509baa881SHong Zhang       ierr = PetscObjectReference((PetscObject)A);CHKERRQ(ierr);
14609baa881SHong Zhang     } else {
1470bacdadaSStefano Zampini       ierr = MatComputeOperator(hessian,MATAIJ,&A);CHKERRQ(ierr);
14809baa881SHong Zhang     }
14909baa881SHong Zhang 
15009baa881SHong Zhang     ierr = MatCreate(PetscObjectComm((PetscObject)A),&B);CHKERRQ(ierr);
15109baa881SHong Zhang     ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
15209baa881SHong Zhang     ierr = MatGetLocalSize(A,&m,&n);CHKERRQ(ierr);
15309baa881SHong Zhang     ierr = MatSetSizes(B,m,n,M,N);CHKERRQ(ierr);
15409baa881SHong Zhang     ierr = MatSetType(B,((PetscObject)A)->type_name);CHKERRQ(ierr);
15509baa881SHong Zhang     ierr = MatSetUp(B);CHKERRQ(ierr);
15609baa881SHong Zhang     ierr = MatSetOption(B,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_FALSE);CHKERRQ(ierr);
15709baa881SHong Zhang 
15809baa881SHong Zhang     ierr = TaoDefaultComputeHessian(tao,x,B,B,NULL);CHKERRQ(ierr);
15909baa881SHong Zhang 
16009baa881SHong Zhang     ierr = MatDuplicate(B,MAT_COPY_VALUES,&D);CHKERRQ(ierr);
16109baa881SHong Zhang     ierr = MatAYPX(D,-1.0,A,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr);
16209baa881SHong Zhang     ierr = MatNorm(D,NORM_FROBENIUS,&nrm);CHKERRQ(ierr);
16309baa881SHong Zhang     ierr = MatNorm(A,NORM_FROBENIUS,&gnorm);CHKERRQ(ierr);
16409baa881SHong Zhang     ierr = MatDestroy(&D);CHKERRQ(ierr);
16509baa881SHong Zhang     if (!gnorm) gnorm = 1; /* just in case */
16609baa881SHong Zhang     ierr = PetscViewerASCIIPrintf(viewer,"  ||H - Hfd||_F/||H||_F = %g, ||H - Hfd||_F = %g\n",(double)(nrm/gnorm),(double)nrm);CHKERRQ(ierr);
16709baa881SHong Zhang 
16809baa881SHong Zhang     if (complete_print) {
16909baa881SHong Zhang       ierr = PetscViewerASCIIPrintf(viewer,"  Hand-coded Hessian ----------\n");CHKERRQ(ierr);
170f3b6e7e3SStefano Zampini       ierr = MatView(A,mviewer);CHKERRQ(ierr);
17109baa881SHong Zhang       ierr = PetscViewerASCIIPrintf(viewer,"  Finite difference Hessian ----------\n");CHKERRQ(ierr);
172f49d1c87SHong Zhang       ierr = MatView(B,mviewer);CHKERRQ(ierr);
17309baa881SHong Zhang     }
17409baa881SHong Zhang 
17509baa881SHong Zhang     if (complete_print) {
17609baa881SHong Zhang       PetscInt          Istart, Iend, *ccols, bncols, cncols, j, row;
17709baa881SHong Zhang       PetscScalar       *cvals;
17809baa881SHong Zhang       const PetscInt    *bcols;
17909baa881SHong Zhang       const PetscScalar *bvals;
18009baa881SHong Zhang 
18109baa881SHong Zhang       ierr = MatAYPX(B,-1.0,A,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr);
18209baa881SHong Zhang       ierr = MatCreate(PetscObjectComm((PetscObject)A),&C);CHKERRQ(ierr);
18309baa881SHong Zhang       ierr = MatSetSizes(C,m,n,M,N);CHKERRQ(ierr);
18409baa881SHong Zhang       ierr = MatSetType(C,((PetscObject)A)->type_name);CHKERRQ(ierr);
18509baa881SHong Zhang       ierr = MatSetUp(C);CHKERRQ(ierr);
18609baa881SHong Zhang       ierr = MatSetOption(C,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_FALSE);CHKERRQ(ierr);
18709baa881SHong Zhang       ierr = MatGetOwnershipRange(B,&Istart,&Iend);CHKERRQ(ierr);
18809baa881SHong Zhang 
18909baa881SHong Zhang       for (row = Istart; row < Iend; row++) {
19009baa881SHong Zhang         ierr = MatGetRow(B,row,&bncols,&bcols,&bvals);CHKERRQ(ierr);
19109baa881SHong Zhang         ierr = PetscMalloc2(bncols,&ccols,bncols,&cvals);CHKERRQ(ierr);
19209baa881SHong Zhang         for (j = 0, cncols = 0; j < bncols; j++) {
19309baa881SHong Zhang           if (PetscAbsScalar(bvals[j]) > threshold) {
19409baa881SHong Zhang             ccols[cncols] = bcols[j];
19509baa881SHong Zhang             cvals[cncols] = bvals[j];
19609baa881SHong Zhang             cncols += 1;
19709baa881SHong Zhang           }
19809baa881SHong Zhang         }
19909baa881SHong Zhang         if (cncols) {
20009baa881SHong Zhang           ierr = MatSetValues(C,1,&row,cncols,ccols,cvals,INSERT_VALUES);CHKERRQ(ierr);
20109baa881SHong Zhang         }
20209baa881SHong Zhang         ierr = MatRestoreRow(B,row,&bncols,&bcols,&bvals);CHKERRQ(ierr);
20309baa881SHong Zhang         ierr = PetscFree2(ccols,cvals);CHKERRQ(ierr);
20409baa881SHong Zhang       }
20509baa881SHong Zhang       ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
20609baa881SHong Zhang       ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
20709baa881SHong Zhang       ierr = PetscViewerASCIIPrintf(viewer,"  Finite-difference minus hand-coded Hessian with tolerance %g ----------\n",(double)threshold);CHKERRQ(ierr);
208f49d1c87SHong Zhang       ierr = MatView(C,mviewer);CHKERRQ(ierr);
20909baa881SHong Zhang       ierr = MatDestroy(&C);CHKERRQ(ierr);
21009baa881SHong Zhang     }
21109baa881SHong Zhang     ierr = MatDestroy(&A);CHKERRQ(ierr);
21209baa881SHong Zhang     ierr = MatDestroy(&B);CHKERRQ(ierr);
21309baa881SHong Zhang 
21409baa881SHong Zhang     if (hessian != tao->hessian_pre) {
21509baa881SHong Zhang       hessian = tao->hessian_pre;
21609baa881SHong Zhang       ierr = PetscViewerASCIIPrintf(viewer,"  ---------- Testing Hessian for preconditioner -------------\n");CHKERRQ(ierr);
21709baa881SHong Zhang     } else hessian = NULL;
21809baa881SHong Zhang   }
219f49d1c87SHong Zhang   if (complete_print) {
220f49d1c87SHong Zhang     ierr = PetscViewerPopFormat(mviewer);CHKERRQ(ierr);
22154b73907SStefano Zampini     ierr = PetscViewerDestroy(&mviewer);CHKERRQ(ierr);
222f49d1c87SHong Zhang   }
22309baa881SHong Zhang   ierr = PetscViewerASCIISetTab(viewer,tabs);CHKERRQ(ierr);
22409baa881SHong Zhang   PetscFunctionReturn(0);
22509baa881SHong Zhang }
22609baa881SHong Zhang 
227a7e14dcfSSatish Balay /*@C
228a7e14dcfSSatish Balay    TaoComputeHessian - Computes the Hessian matrix that has been
229a82e8c82SStefano Zampini    set with TaoSetHessian().
230a7e14dcfSSatish Balay 
231441846f8SBarry Smith    Collective on Tao
232a7e14dcfSSatish Balay 
233a7e14dcfSSatish Balay    Input Parameters:
234f4c1ad5cSStefano Zampini +  tao - the Tao solver context
235f4c1ad5cSStefano Zampini -  X   - input vector
236a7e14dcfSSatish Balay 
237a7e14dcfSSatish Balay    Output Parameters:
238a7e14dcfSSatish Balay +  H    - Hessian matrix
239aa6c7ce3SBarry Smith -  Hpre - Preconditioning matrix
240a7e14dcfSSatish Balay 
24109baa881SHong Zhang    Options Database Keys:
24209baa881SHong Zhang +     -tao_test_hessian - compare the user provided Hessian with one compute via finite differences to check for errors
24309baa881SHong 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
244dfe02fe6SHong 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
24509baa881SHong Zhang 
246a7e14dcfSSatish Balay    Notes:
247a7e14dcfSSatish Balay    Most users should not need to explicitly call this routine, as it
248a7e14dcfSSatish Balay    is used internally within the minimization solvers.
249a7e14dcfSSatish Balay 
250a7e14dcfSSatish Balay    TaoComputeHessian() is typically used within minimization
251a7e14dcfSSatish Balay    implementations, so most users would not generally call this routine
252a7e14dcfSSatish Balay    themselves.
253a7e14dcfSSatish Balay 
25409baa881SHong Zhang    Developer Notes:
25509baa881SHong Zhang    The Hessian test mechanism follows SNESTestJacobian().
25609baa881SHong Zhang 
257a7e14dcfSSatish Balay    Level: developer
258a7e14dcfSSatish Balay 
259a82e8c82SStefano Zampini .seealso: TaoComputeObjective(), TaoComputeObjectiveAndGradient(), TaoSetHessian()
260a7e14dcfSSatish Balay @*/
261ffad9901SBarry Smith PetscErrorCode TaoComputeHessian(Tao tao, Vec X, Mat H, Mat Hpre)
262a7e14dcfSSatish Balay {
263a7e14dcfSSatish Balay   PetscErrorCode ierr;
26487f595a5SBarry Smith 
265a7e14dcfSSatish Balay   PetscFunctionBegin;
266441846f8SBarry Smith   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
267a7e14dcfSSatish Balay   PetscValidHeaderSpecific(X, VEC_CLASSID,2);
268a7e14dcfSSatish Balay   PetscCheckSameComm(tao,1,X,2);
269*3c859ba3SBarry Smith   PetscCheck(tao->ops->computehessian,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Must call TaoSetHessian() first");
270a7e14dcfSSatish Balay   ++tao->nhess;
2718860a134SJunchao Zhang   ierr = VecLockReadPush(X);CHKERRQ(ierr);
2720ebee16dSLisandro Dalcin   ierr = PetscLogEventBegin(TAO_HessianEval,tao,X,H,Hpre);CHKERRQ(ierr);
273441846f8SBarry Smith   PetscStackPush("Tao user Hessian function");
274ffad9901SBarry Smith   ierr = (*tao->ops->computehessian)(tao,X,H,Hpre,tao->user_hessP);CHKERRQ(ierr);
275a7e14dcfSSatish Balay   PetscStackPop;
2760ebee16dSLisandro Dalcin   ierr = PetscLogEventEnd(TAO_HessianEval,tao,X,H,Hpre);CHKERRQ(ierr);
2778860a134SJunchao Zhang   ierr = VecLockReadPop(X);CHKERRQ(ierr);
27809baa881SHong Zhang 
27909baa881SHong Zhang   ierr = TaoTestHessian(tao);CHKERRQ(ierr);
280a7e14dcfSSatish Balay   PetscFunctionReturn(0);
281a7e14dcfSSatish Balay }
282a7e14dcfSSatish Balay 
283a7e14dcfSSatish Balay /*@C
284a7e14dcfSSatish Balay    TaoComputeJacobian - Computes the Jacobian matrix that has been
285a7e14dcfSSatish Balay    set with TaoSetJacobianRoutine().
286a7e14dcfSSatish Balay 
287441846f8SBarry Smith    Collective on Tao
288a7e14dcfSSatish Balay 
289a7e14dcfSSatish Balay    Input Parameters:
290f4c1ad5cSStefano Zampini +  tao - the Tao solver context
291f4c1ad5cSStefano Zampini -  X   - input vector
292a7e14dcfSSatish Balay 
293a7e14dcfSSatish Balay    Output Parameters:
294f4c1ad5cSStefano Zampini +  J    - Jacobian matrix
295f4c1ad5cSStefano Zampini -  Jpre - Preconditioning matrix
296a7e14dcfSSatish Balay 
297a7e14dcfSSatish Balay    Notes:
298a7e14dcfSSatish Balay    Most users should not need to explicitly call this routine, as it
299a7e14dcfSSatish Balay    is used internally within the minimization solvers.
300a7e14dcfSSatish Balay 
301a7e14dcfSSatish Balay    TaoComputeJacobian() is typically used within minimization
302a7e14dcfSSatish Balay    implementations, so most users would not generally call this routine
303a7e14dcfSSatish Balay    themselves.
304a7e14dcfSSatish Balay 
305a7e14dcfSSatish Balay    Level: developer
306a7e14dcfSSatish Balay 
307f4c1ad5cSStefano Zampini .seealso: TaoComputeObjective(), TaoComputeObjectiveAndGradient(), TaoSetJacobianRoutine()
308a7e14dcfSSatish Balay @*/
309ffad9901SBarry Smith PetscErrorCode TaoComputeJacobian(Tao tao, Vec X, Mat J, Mat Jpre)
310a7e14dcfSSatish Balay {
311a7e14dcfSSatish Balay   PetscErrorCode ierr;
31287f595a5SBarry Smith 
313a7e14dcfSSatish Balay   PetscFunctionBegin;
314441846f8SBarry Smith   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
315a7e14dcfSSatish Balay   PetscValidHeaderSpecific(X, VEC_CLASSID,2);
316a7e14dcfSSatish Balay   PetscCheckSameComm(tao,1,X,2);
317*3c859ba3SBarry Smith   PetscCheck(tao->ops->computejacobian,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Must call TaoSetJacobian() first");
318a7e14dcfSSatish Balay   ++tao->njac;
3198860a134SJunchao Zhang   ierr = VecLockReadPush(X);CHKERRQ(ierr);
3200ebee16dSLisandro Dalcin   ierr = PetscLogEventBegin(TAO_JacobianEval,tao,X,J,Jpre);CHKERRQ(ierr);
321441846f8SBarry Smith   PetscStackPush("Tao user Jacobian function");
322ffad9901SBarry Smith   ierr = (*tao->ops->computejacobian)(tao,X,J,Jpre,tao->user_jacP);CHKERRQ(ierr);
323a7e14dcfSSatish Balay   PetscStackPop;
3240ebee16dSLisandro Dalcin   ierr = PetscLogEventEnd(TAO_JacobianEval,tao,X,J,Jpre);CHKERRQ(ierr);
3258860a134SJunchao Zhang   ierr = VecLockReadPop(X);CHKERRQ(ierr);
326a7e14dcfSSatish Balay   PetscFunctionReturn(0);
327a7e14dcfSSatish Balay }
328a7e14dcfSSatish Balay 
329a7e14dcfSSatish Balay /*@C
3304a48860cSAlp Dener    TaoComputeResidualJacobian - Computes the least-squares residual Jacobian matrix that has been
331a6fed868SAlp Dener    set with TaoSetJacobianResidual().
3324a48860cSAlp Dener 
3334a48860cSAlp Dener    Collective on Tao
3344a48860cSAlp Dener 
3354a48860cSAlp Dener    Input Parameters:
3364a48860cSAlp Dener +  tao - the Tao solver context
3374a48860cSAlp Dener -  X   - input vector
3384a48860cSAlp Dener 
3394a48860cSAlp Dener    Output Parameters:
3404a48860cSAlp Dener +  J    - Jacobian matrix
3414a48860cSAlp Dener -  Jpre - Preconditioning matrix
3424a48860cSAlp Dener 
3434a48860cSAlp Dener    Notes:
3444a48860cSAlp Dener    Most users should not need to explicitly call this routine, as it
3454a48860cSAlp Dener    is used internally within the minimization solvers.
3464a48860cSAlp Dener 
3474a48860cSAlp Dener    TaoComputeResidualJacobian() is typically used within least-squares
3484a48860cSAlp Dener    implementations, so most users would not generally call this routine
3494a48860cSAlp Dener    themselves.
3504a48860cSAlp Dener 
3514a48860cSAlp Dener    Level: developer
3524a48860cSAlp Dener 
353a6fed868SAlp Dener .seealso: TaoComputeResidual(), TaoSetJacobianResidual()
3544a48860cSAlp Dener @*/
3554a48860cSAlp Dener PetscErrorCode TaoComputeResidualJacobian(Tao tao, Vec X, Mat J, Mat Jpre)
3564a48860cSAlp Dener {
3574a48860cSAlp Dener   PetscErrorCode ierr;
3584a48860cSAlp Dener 
3594a48860cSAlp Dener   PetscFunctionBegin;
3604a48860cSAlp Dener   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
3614a48860cSAlp Dener   PetscValidHeaderSpecific(X, VEC_CLASSID,2);
3624a48860cSAlp Dener   PetscCheckSameComm(tao,1,X,2);
363*3c859ba3SBarry Smith   PetscCheck(tao->ops->computeresidualjacobian,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Must call TaoSetResidualJacobian() first");
3644a48860cSAlp Dener   ++tao->njac;
3658860a134SJunchao Zhang   ierr = VecLockReadPush(X);CHKERRQ(ierr);
3664a48860cSAlp Dener   ierr = PetscLogEventBegin(TAO_JacobianEval,tao,X,J,Jpre);CHKERRQ(ierr);
3674a48860cSAlp Dener   PetscStackPush("Tao user least-squares residual Jacobian function");
3684a48860cSAlp Dener   ierr = (*tao->ops->computeresidualjacobian)(tao,X,J,Jpre,tao->user_lsjacP);CHKERRQ(ierr);
3694a48860cSAlp Dener   PetscStackPop;
3704a48860cSAlp Dener   ierr = PetscLogEventEnd(TAO_JacobianEval,tao,X,J,Jpre);CHKERRQ(ierr);
3718860a134SJunchao Zhang   ierr = VecLockReadPop(X);CHKERRQ(ierr);
3724a48860cSAlp Dener   PetscFunctionReturn(0);
3734a48860cSAlp Dener }
3744a48860cSAlp Dener 
3754a48860cSAlp Dener /*@C
376a7e14dcfSSatish Balay    TaoComputeJacobianState - Computes the Jacobian matrix that has been
377a7e14dcfSSatish Balay    set with TaoSetJacobianStateRoutine().
378a7e14dcfSSatish Balay 
379441846f8SBarry Smith    Collective on Tao
380a7e14dcfSSatish Balay 
381a7e14dcfSSatish Balay    Input Parameters:
382f4c1ad5cSStefano Zampini +  tao - the Tao solver context
383f4c1ad5cSStefano Zampini -  X   - input vector
384a7e14dcfSSatish Balay 
385a7e14dcfSSatish Balay    Output Parameters:
3866b867d5aSJose E. Roman +  J    - Jacobian matrix
3876b867d5aSJose E. Roman .  Jpre - Preconditioning matrix
3886b867d5aSJose E. Roman -  Jinv -
389a7e14dcfSSatish Balay 
390a7e14dcfSSatish Balay    Notes:
391a7e14dcfSSatish Balay    Most users should not need to explicitly call this routine, as it
392a7e14dcfSSatish Balay    is used internally within the minimization solvers.
393a7e14dcfSSatish Balay 
394a7e14dcfSSatish Balay    TaoComputeJacobianState() is typically used within minimization
395a7e14dcfSSatish Balay    implementations, so most users would not generally call this routine
396a7e14dcfSSatish Balay    themselves.
397a7e14dcfSSatish Balay 
398a7e14dcfSSatish Balay    Level: developer
399a7e14dcfSSatish Balay 
400a7e14dcfSSatish Balay .seealso: TaoComputeObjective(), TaoComputeObjectiveAndGradient(), TaoSetJacobianStateRoutine(), TaoComputeJacobianDesign(), TaoSetStateDesignIS()
401a7e14dcfSSatish Balay @*/
402ffad9901SBarry Smith PetscErrorCode TaoComputeJacobianState(Tao tao, Vec X, Mat J, Mat Jpre, Mat Jinv)
403a7e14dcfSSatish Balay {
404a7e14dcfSSatish Balay   PetscErrorCode ierr;
40545cf516eSBarry Smith 
406a7e14dcfSSatish Balay   PetscFunctionBegin;
407441846f8SBarry Smith   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
408a7e14dcfSSatish Balay   PetscValidHeaderSpecific(X, VEC_CLASSID,2);
409a7e14dcfSSatish Balay   PetscCheckSameComm(tao,1,X,2);
410*3c859ba3SBarry Smith   PetscCheck(tao->ops->computejacobianstate,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Must call TaoSetJacobianState() first");
411a7e14dcfSSatish Balay   ++tao->njac_state;
4128860a134SJunchao Zhang   ierr = VecLockReadPush(X);CHKERRQ(ierr);
4130ebee16dSLisandro Dalcin   ierr = PetscLogEventBegin(TAO_JacobianEval,tao,X,J,Jpre);CHKERRQ(ierr);
414441846f8SBarry Smith   PetscStackPush("Tao user Jacobian(state) function");
415ffad9901SBarry Smith   ierr = (*tao->ops->computejacobianstate)(tao,X,J,Jpre,Jinv,tao->user_jac_stateP);CHKERRQ(ierr);
416a7e14dcfSSatish Balay   PetscStackPop;
4170ebee16dSLisandro Dalcin   ierr = PetscLogEventEnd(TAO_JacobianEval,tao,X,J,Jpre);CHKERRQ(ierr);
4188860a134SJunchao Zhang   ierr = VecLockReadPop(X);CHKERRQ(ierr);
419a7e14dcfSSatish Balay   PetscFunctionReturn(0);
420a7e14dcfSSatish Balay }
421a7e14dcfSSatish Balay 
422a7e14dcfSSatish Balay /*@C
423a7e14dcfSSatish Balay    TaoComputeJacobianDesign - Computes the Jacobian matrix that has been
424a7e14dcfSSatish Balay    set with TaoSetJacobianDesignRoutine().
425a7e14dcfSSatish Balay 
426441846f8SBarry Smith    Collective on Tao
427a7e14dcfSSatish Balay 
428a7e14dcfSSatish Balay    Input Parameters:
429f4c1ad5cSStefano Zampini +  tao - the Tao solver context
430f4c1ad5cSStefano Zampini -  X   - input vector
431a7e14dcfSSatish Balay 
432a7e14dcfSSatish Balay    Output Parameters:
433f4c1ad5cSStefano Zampini .  J - Jacobian matrix
434a7e14dcfSSatish Balay 
435a7e14dcfSSatish Balay    Notes:
436a7e14dcfSSatish Balay    Most users should not need to explicitly call this routine, as it
437a7e14dcfSSatish Balay    is used internally within the minimization solvers.
438a7e14dcfSSatish Balay 
439a7e14dcfSSatish Balay    TaoComputeJacobianDesign() is typically used within minimization
440a7e14dcfSSatish Balay    implementations, so most users would not generally call this routine
441a7e14dcfSSatish Balay    themselves.
442a7e14dcfSSatish Balay 
443a7e14dcfSSatish Balay    Level: developer
444a7e14dcfSSatish Balay 
445a7e14dcfSSatish Balay .seealso:  TaoComputeObjective(), TaoComputeObjectiveAndGradient(), TaoSetJacobianDesignRoutine(), TaoComputeJacobianDesign(), TaoSetStateDesignIS()
446a7e14dcfSSatish Balay @*/
44794ab13aaSBarry Smith PetscErrorCode TaoComputeJacobianDesign(Tao tao, Vec X, Mat J)
448a7e14dcfSSatish Balay {
449a7e14dcfSSatish Balay   PetscErrorCode ierr;
45087f595a5SBarry Smith 
451a7e14dcfSSatish Balay   PetscFunctionBegin;
452441846f8SBarry Smith   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
453a7e14dcfSSatish Balay   PetscValidHeaderSpecific(X, VEC_CLASSID,2);
454a7e14dcfSSatish Balay   PetscCheckSameComm(tao,1,X,2);
455*3c859ba3SBarry Smith   PetscCheck(tao->ops->computejacobiandesign,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Must call TaoSetJacobianDesign() first");
456a7e14dcfSSatish Balay   ++tao->njac_design;
4578860a134SJunchao Zhang   ierr = VecLockReadPush(X);CHKERRQ(ierr);
4580ebee16dSLisandro Dalcin   ierr = PetscLogEventBegin(TAO_JacobianEval,tao,X,J,NULL);CHKERRQ(ierr);
459441846f8SBarry Smith   PetscStackPush("Tao user Jacobian(design) function");
460a7e14dcfSSatish Balay   ierr = (*tao->ops->computejacobiandesign)(tao,X,J,tao->user_jac_designP);CHKERRQ(ierr);
461a7e14dcfSSatish Balay   PetscStackPop;
4620ebee16dSLisandro Dalcin   ierr = PetscLogEventEnd(TAO_JacobianEval,tao,X,J,NULL);CHKERRQ(ierr);
4638860a134SJunchao Zhang   ierr = VecLockReadPop(X);CHKERRQ(ierr);
464a7e14dcfSSatish Balay   PetscFunctionReturn(0);
465a7e14dcfSSatish Balay }
466a7e14dcfSSatish Balay 
467a7e14dcfSSatish Balay /*@C
468a7e14dcfSSatish Balay    TaoSetJacobianRoutine - Sets the function to compute the Jacobian as well as the location to store the matrix.
469a7e14dcfSSatish Balay 
470441846f8SBarry Smith    Logically collective on Tao
471a7e14dcfSSatish Balay 
472a7e14dcfSSatish Balay    Input Parameters:
473441846f8SBarry Smith +  tao  - the Tao context
474a7e14dcfSSatish Balay .  J    - Matrix used for the jacobian
475a7e14dcfSSatish Balay .  Jpre - Matrix that will be used operated on by preconditioner, can be same as J
476f4c1ad5cSStefano Zampini .  func - Jacobian evaluation routine
477a7e14dcfSSatish Balay -  ctx  - [optional] user-defined context for private data for the
4786c23d075SBarry Smith           Jacobian evaluation routine (may be NULL)
479a7e14dcfSSatish Balay 
480f4c1ad5cSStefano Zampini    Calling sequence of func:
481f4c1ad5cSStefano Zampini $    func(Tao tao,Vec x,Mat J,Mat Jpre,void *ctx);
482a7e14dcfSSatish Balay 
483441846f8SBarry Smith +  tao  - the Tao  context
484a7e14dcfSSatish Balay .  x    - input vector
485a7e14dcfSSatish Balay .  J    - Jacobian matrix
486f4c1ad5cSStefano Zampini .  Jpre - preconditioning matrix, usually the same as J
487a7e14dcfSSatish Balay -  ctx  - [optional] user-defined Jacobian context
488a7e14dcfSSatish Balay 
489a7e14dcfSSatish Balay    Level: intermediate
490a7e14dcfSSatish Balay @*/
491ffad9901SBarry Smith PetscErrorCode TaoSetJacobianRoutine(Tao tao, Mat J, Mat Jpre, PetscErrorCode (*func)(Tao, Vec, Mat, Mat, void*), void *ctx)
492a7e14dcfSSatish Balay {
493a7e14dcfSSatish Balay   PetscErrorCode ierr;
494f4c1ad5cSStefano Zampini 
495a7e14dcfSSatish Balay   PetscFunctionBegin;
496441846f8SBarry Smith   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
497a7e14dcfSSatish Balay   if (J) {
498a7e14dcfSSatish Balay     PetscValidHeaderSpecific(J,MAT_CLASSID,2);
499a7e14dcfSSatish Balay     PetscCheckSameComm(tao,1,J,2);
500a7e14dcfSSatish Balay   }
501a7e14dcfSSatish Balay   if (Jpre) {
502a7e14dcfSSatish Balay     PetscValidHeaderSpecific(Jpre,MAT_CLASSID,3);
503a7e14dcfSSatish Balay     PetscCheckSameComm(tao,1,Jpre,3);
504a7e14dcfSSatish Balay   }
505a7e14dcfSSatish Balay   if (ctx) {
506a7e14dcfSSatish Balay     tao->user_jacP = ctx;
507a7e14dcfSSatish Balay   }
508a7e14dcfSSatish Balay   if (func) {
509a7e14dcfSSatish Balay     tao->ops->computejacobian = func;
510a7e14dcfSSatish Balay   }
511a7e14dcfSSatish Balay   if (J) {
512a7e14dcfSSatish Balay     ierr = PetscObjectReference((PetscObject)J);CHKERRQ(ierr);
51345cf516eSBarry Smith     ierr = MatDestroy(&tao->jacobian);CHKERRQ(ierr);
514a7e14dcfSSatish Balay     tao->jacobian = J;
515a7e14dcfSSatish Balay   }
516a7e14dcfSSatish Balay   if (Jpre) {
517a7e14dcfSSatish Balay     ierr = PetscObjectReference((PetscObject)Jpre);CHKERRQ(ierr);
51845cf516eSBarry Smith     ierr = MatDestroy(&tao->jacobian_pre);CHKERRQ(ierr);
519a7e14dcfSSatish Balay     tao->jacobian_pre=Jpre;
520a7e14dcfSSatish Balay   }
521a7e14dcfSSatish Balay   PetscFunctionReturn(0);
522a7e14dcfSSatish Balay }
523a7e14dcfSSatish Balay 
524a7e14dcfSSatish Balay /*@C
5254ffbe8acSAlp Dener    TaoSetJacobianResidualRoutine - Sets the function to compute the least-squares residual Jacobian as well as the
5264a48860cSAlp Dener    location to store the matrix.
5274a48860cSAlp Dener 
5284a48860cSAlp Dener    Logically collective on Tao
5294a48860cSAlp Dener 
5304a48860cSAlp Dener    Input Parameters:
5314a48860cSAlp Dener +  tao  - the Tao context
5324a48860cSAlp Dener .  J    - Matrix used for the jacobian
5334a48860cSAlp Dener .  Jpre - Matrix that will be used operated on by preconditioner, can be same as J
5344a48860cSAlp Dener .  func - Jacobian evaluation routine
5354a48860cSAlp Dener -  ctx  - [optional] user-defined context for private data for the
5364a48860cSAlp Dener           Jacobian evaluation routine (may be NULL)
5374a48860cSAlp Dener 
5384a48860cSAlp Dener    Calling sequence of func:
5394a48860cSAlp Dener $    func(Tao tao,Vec x,Mat J,Mat Jpre,void *ctx);
5404a48860cSAlp Dener 
5414a48860cSAlp Dener +  tao  - the Tao  context
5424a48860cSAlp Dener .  x    - input vector
5434a48860cSAlp Dener .  J    - Jacobian matrix
5444a48860cSAlp Dener .  Jpre - preconditioning matrix, usually the same as J
5454a48860cSAlp Dener -  ctx  - [optional] user-defined Jacobian context
5464a48860cSAlp Dener 
5474a48860cSAlp Dener    Level: intermediate
5484a48860cSAlp Dener @*/
5494ffbe8acSAlp Dener PetscErrorCode TaoSetJacobianResidualRoutine(Tao tao, Mat J, Mat Jpre, PetscErrorCode (*func)(Tao, Vec, Mat, Mat, void*), void *ctx)
5504a48860cSAlp Dener {
5514a48860cSAlp Dener   PetscErrorCode ierr;
5524a48860cSAlp Dener 
5534a48860cSAlp Dener   PetscFunctionBegin;
5544a48860cSAlp Dener   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
5554a48860cSAlp Dener   if (J) {
5564a48860cSAlp Dener     PetscValidHeaderSpecific(J,MAT_CLASSID,2);
5574a48860cSAlp Dener     PetscCheckSameComm(tao,1,J,2);
5584a48860cSAlp Dener   }
5594a48860cSAlp Dener   if (Jpre) {
5604a48860cSAlp Dener     PetscValidHeaderSpecific(Jpre,MAT_CLASSID,3);
5614a48860cSAlp Dener     PetscCheckSameComm(tao,1,Jpre,3);
5624a48860cSAlp Dener   }
5634a48860cSAlp Dener   if (ctx) {
5644a48860cSAlp Dener     tao->user_lsjacP = ctx;
5654a48860cSAlp Dener   }
5664a48860cSAlp Dener   if (func) {
5674a48860cSAlp Dener     tao->ops->computeresidualjacobian = func;
5684a48860cSAlp Dener   }
5694a48860cSAlp Dener   if (J) {
5704a48860cSAlp Dener     ierr = PetscObjectReference((PetscObject)J);CHKERRQ(ierr);
5714a48860cSAlp Dener     ierr = MatDestroy(&tao->ls_jac);CHKERRQ(ierr);
5724a48860cSAlp Dener     tao->ls_jac = J;
5734a48860cSAlp Dener   }
5744a48860cSAlp Dener   if (Jpre) {
5754a48860cSAlp Dener     ierr = PetscObjectReference((PetscObject)Jpre);CHKERRQ(ierr);
5764a48860cSAlp Dener     ierr = MatDestroy(&tao->ls_jac_pre);CHKERRQ(ierr);
5774a48860cSAlp Dener     tao->ls_jac_pre=Jpre;
5784a48860cSAlp Dener   }
5794a48860cSAlp Dener   PetscFunctionReturn(0);
5804a48860cSAlp Dener }
5814a48860cSAlp Dener 
5824a48860cSAlp Dener /*@C
583a7e14dcfSSatish Balay    TaoSetJacobianStateRoutine - Sets the function to compute the Jacobian
584a7e14dcfSSatish Balay    (and its inverse) of the constraint function with respect to the state variables.
585a7e14dcfSSatish Balay    Used only for pde-constrained optimization.
586a7e14dcfSSatish Balay 
587441846f8SBarry Smith    Logically collective on Tao
588a7e14dcfSSatish Balay 
589a7e14dcfSSatish Balay    Input Parameters:
590441846f8SBarry Smith +  tao  - the Tao context
591a7e14dcfSSatish Balay .  J    - Matrix used for the jacobian
5926c23d075SBarry Smith .  Jpre - Matrix that will be used operated on by PETSc preconditioner, can be same as J.  Only used if Jinv is NULL
5936c23d075SBarry 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.
594f4c1ad5cSStefano Zampini .  func - Jacobian evaluation routine
595a7e14dcfSSatish Balay -  ctx  - [optional] user-defined context for private data for the
5966c23d075SBarry Smith           Jacobian evaluation routine (may be NULL)
597a7e14dcfSSatish Balay 
598f4c1ad5cSStefano Zampini    Calling sequence of func:
599f4c1ad5cSStefano Zampini $    func(Tao tao,Vec x,Mat J,Mat Jpre,Mat Jinv,void *ctx);
600a7e14dcfSSatish Balay 
601441846f8SBarry Smith +  tao  - the Tao  context
602a7e14dcfSSatish Balay .  x    - input vector
603a7e14dcfSSatish Balay .  J    - Jacobian matrix
604a7e14dcfSSatish Balay .  Jpre - preconditioner matrix, usually the same as J
605a7e14dcfSSatish Balay .  Jinv - inverse of J
606a7e14dcfSSatish Balay -  ctx  - [optional] user-defined Jacobian context
607a7e14dcfSSatish Balay 
608a7e14dcfSSatish Balay    Level: intermediate
609f4c1ad5cSStefano Zampini .seealso: TaoComputeJacobianState(), TaoSetJacobianDesignRoutine(), TaoSetStateDesignIS()
610a7e14dcfSSatish Balay @*/
611ffad9901SBarry Smith PetscErrorCode TaoSetJacobianStateRoutine(Tao tao, Mat J, Mat Jpre, Mat Jinv, PetscErrorCode (*func)(Tao, Vec, Mat, Mat, Mat, void*), void *ctx)
612a7e14dcfSSatish Balay {
613a7e14dcfSSatish Balay   PetscErrorCode ierr;
614f4c1ad5cSStefano Zampini 
615a7e14dcfSSatish Balay   PetscFunctionBegin;
616441846f8SBarry Smith   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
617a7e14dcfSSatish Balay   if (J) {
618a7e14dcfSSatish Balay     PetscValidHeaderSpecific(J,MAT_CLASSID,2);
619a7e14dcfSSatish Balay     PetscCheckSameComm(tao,1,J,2);
620a7e14dcfSSatish Balay   }
621a7e14dcfSSatish Balay   if (Jpre) {
622a7e14dcfSSatish Balay     PetscValidHeaderSpecific(Jpre,MAT_CLASSID,3);
623a7e14dcfSSatish Balay     PetscCheckSameComm(tao,1,Jpre,3);
624a7e14dcfSSatish Balay   }
625a7e14dcfSSatish Balay   if (Jinv) {
626a7e14dcfSSatish Balay     PetscValidHeaderSpecific(Jinv,MAT_CLASSID,4);
627a7e14dcfSSatish Balay     PetscCheckSameComm(tao,1,Jinv,4);
628a7e14dcfSSatish Balay   }
629a7e14dcfSSatish Balay   if (ctx) {
630a7e14dcfSSatish Balay     tao->user_jac_stateP = ctx;
631a7e14dcfSSatish Balay   }
632a7e14dcfSSatish Balay   if (func) {
633a7e14dcfSSatish Balay     tao->ops->computejacobianstate = func;
634a7e14dcfSSatish Balay   }
635a7e14dcfSSatish Balay   if (J) {
636a7e14dcfSSatish Balay     ierr = PetscObjectReference((PetscObject)J);CHKERRQ(ierr);
63745cf516eSBarry Smith     ierr = MatDestroy(&tao->jacobian_state);CHKERRQ(ierr);
638a7e14dcfSSatish Balay     tao->jacobian_state = J;
639a7e14dcfSSatish Balay   }
640a7e14dcfSSatish Balay   if (Jpre) {
641a7e14dcfSSatish Balay     ierr = PetscObjectReference((PetscObject)Jpre);CHKERRQ(ierr);
64245cf516eSBarry Smith     ierr = MatDestroy(&tao->jacobian_state_pre);CHKERRQ(ierr);
643a7e14dcfSSatish Balay     tao->jacobian_state_pre=Jpre;
644a7e14dcfSSatish Balay   }
645a7e14dcfSSatish Balay   if (Jinv) {
646a7e14dcfSSatish Balay     ierr = PetscObjectReference((PetscObject)Jinv);CHKERRQ(ierr);
64745cf516eSBarry Smith     ierr = MatDestroy(&tao->jacobian_state_inv);CHKERRQ(ierr);
648a7e14dcfSSatish Balay     tao->jacobian_state_inv=Jinv;
649a7e14dcfSSatish Balay   }
650a7e14dcfSSatish Balay   PetscFunctionReturn(0);
651a7e14dcfSSatish Balay }
652a7e14dcfSSatish Balay 
653a7e14dcfSSatish Balay /*@C
654a7e14dcfSSatish Balay    TaoSetJacobianDesignRoutine - Sets the function to compute the Jacobian of
655a7e14dcfSSatish Balay    the constraint function with respect to the design variables.  Used only for
656a7e14dcfSSatish Balay    pde-constrained optimization.
657a7e14dcfSSatish Balay 
658441846f8SBarry Smith    Logically collective on Tao
659a7e14dcfSSatish Balay 
660a7e14dcfSSatish Balay    Input Parameters:
661441846f8SBarry Smith +  tao  - the Tao context
662a7e14dcfSSatish Balay .  J    - Matrix used for the jacobian
663f4c1ad5cSStefano Zampini .  func - Jacobian evaluation routine
664a7e14dcfSSatish Balay -  ctx  - [optional] user-defined context for private data for the
6656c23d075SBarry Smith           Jacobian evaluation routine (may be NULL)
666a7e14dcfSSatish Balay 
667f4c1ad5cSStefano Zampini    Calling sequence of func:
668f4c1ad5cSStefano Zampini $    func(Tao tao,Vec x,Mat J,void *ctx);
669a7e14dcfSSatish Balay 
670441846f8SBarry Smith +  tao - the Tao  context
671a7e14dcfSSatish Balay .  x   - input vector
672a7e14dcfSSatish Balay .  J   - Jacobian matrix
673a7e14dcfSSatish Balay -  ctx - [optional] user-defined Jacobian context
674a7e14dcfSSatish Balay 
675a7e14dcfSSatish Balay    Level: intermediate
676f4c1ad5cSStefano Zampini 
677a7e14dcfSSatish Balay .seealso: TaoComputeJacobianDesign(), TaoSetJacobianStateRoutine(), TaoSetStateDesignIS()
678a7e14dcfSSatish Balay @*/
67994ab13aaSBarry Smith PetscErrorCode TaoSetJacobianDesignRoutine(Tao tao, Mat J, PetscErrorCode (*func)(Tao, Vec, Mat, void*), void *ctx)
680a7e14dcfSSatish Balay {
681a7e14dcfSSatish Balay   PetscErrorCode ierr;
68245cf516eSBarry Smith 
683a7e14dcfSSatish Balay   PetscFunctionBegin;
684441846f8SBarry Smith   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
685a7e14dcfSSatish Balay   if (J) {
686a7e14dcfSSatish Balay     PetscValidHeaderSpecific(J,MAT_CLASSID,2);
687a7e14dcfSSatish Balay     PetscCheckSameComm(tao,1,J,2);
688a7e14dcfSSatish Balay   }
689a7e14dcfSSatish Balay   if (ctx) {
690a7e14dcfSSatish Balay     tao->user_jac_designP = ctx;
691a7e14dcfSSatish Balay   }
692a7e14dcfSSatish Balay   if (func) {
693a7e14dcfSSatish Balay     tao->ops->computejacobiandesign = func;
694a7e14dcfSSatish Balay   }
695a7e14dcfSSatish Balay   if (J) {
696a7e14dcfSSatish Balay     ierr = PetscObjectReference((PetscObject)J);CHKERRQ(ierr);
69745cf516eSBarry Smith     ierr = MatDestroy(&tao->jacobian_design);CHKERRQ(ierr);
698a7e14dcfSSatish Balay     tao->jacobian_design = J;
699a7e14dcfSSatish Balay   }
700a7e14dcfSSatish Balay   PetscFunctionReturn(0);
701a7e14dcfSSatish Balay }
702a7e14dcfSSatish Balay 
703a7e14dcfSSatish Balay /*@
704441846f8SBarry Smith    TaoSetStateDesignIS - Indicate to the Tao which variables in the
705a7e14dcfSSatish Balay    solution vector are state variables and which are design.  Only applies to
706a7e14dcfSSatish Balay    pde-constrained optimization.
707a7e14dcfSSatish Balay 
708441846f8SBarry Smith    Logically Collective on Tao
709a7e14dcfSSatish Balay 
710a7e14dcfSSatish Balay    Input Parameters:
711441846f8SBarry Smith +  tao  - The Tao context
712a7e14dcfSSatish Balay .  s_is - the index set corresponding to the state variables
713a7e14dcfSSatish Balay -  d_is - the index set corresponding to the design variables
714a7e14dcfSSatish Balay 
715a7e14dcfSSatish Balay    Level: intermediate
716a7e14dcfSSatish Balay 
717a7e14dcfSSatish Balay .seealso: TaoSetJacobianStateRoutine(), TaoSetJacobianDesignRoutine()
718a7e14dcfSSatish Balay @*/
719441846f8SBarry Smith PetscErrorCode TaoSetStateDesignIS(Tao tao, IS s_is, IS d_is)
720a7e14dcfSSatish Balay {
721a7e14dcfSSatish Balay   PetscErrorCode ierr;
72245cf516eSBarry Smith 
72345cf516eSBarry Smith   PetscFunctionBegin;
72445cf516eSBarry Smith   ierr = PetscObjectReference((PetscObject)s_is);CHKERRQ(ierr);
72545cf516eSBarry Smith   ierr = ISDestroy(&tao->state_is);CHKERRQ(ierr);
726a7e14dcfSSatish Balay   tao->state_is = s_is;
72745cf516eSBarry Smith   ierr = PetscObjectReference((PetscObject)(d_is));CHKERRQ(ierr);
72845cf516eSBarry Smith   ierr = ISDestroy(&tao->design_is);CHKERRQ(ierr);
729a7e14dcfSSatish Balay   tao->design_is = d_is;
730a7e14dcfSSatish Balay   PetscFunctionReturn(0);
731a7e14dcfSSatish Balay }
732a7e14dcfSSatish Balay 
733a7e14dcfSSatish Balay /*@C
734a7e14dcfSSatish Balay    TaoComputeJacobianEquality - Computes the Jacobian matrix that has been
735a7e14dcfSSatish Balay    set with TaoSetJacobianEqualityRoutine().
736a7e14dcfSSatish Balay 
737441846f8SBarry Smith    Collective on Tao
738a7e14dcfSSatish Balay 
739a7e14dcfSSatish Balay    Input Parameters:
740f4c1ad5cSStefano Zampini +  tao - the Tao solver context
741f4c1ad5cSStefano Zampini -  X   - input vector
742a7e14dcfSSatish Balay 
743a7e14dcfSSatish Balay    Output Parameters:
744f4c1ad5cSStefano Zampini +  J    - Jacobian matrix
745f4c1ad5cSStefano Zampini -  Jpre - Preconditioning matrix
746a7e14dcfSSatish Balay 
747a7e14dcfSSatish Balay    Notes:
748a7e14dcfSSatish Balay    Most users should not need to explicitly call this routine, as it
749a7e14dcfSSatish Balay    is used internally within the minimization solvers.
750a7e14dcfSSatish Balay 
751a7e14dcfSSatish Balay    Level: developer
752a7e14dcfSSatish Balay 
753a7e14dcfSSatish Balay .seealso:  TaoComputeObjective(), TaoComputeObjectiveAndGradient(), TaoSetJacobianStateRoutine(), TaoComputeJacobianDesign(), TaoSetStateDesignIS()
754a7e14dcfSSatish Balay @*/
755ffad9901SBarry Smith PetscErrorCode TaoComputeJacobianEquality(Tao tao, Vec X, Mat J, Mat Jpre)
756a7e14dcfSSatish Balay {
757a7e14dcfSSatish Balay   PetscErrorCode ierr;
75845cf516eSBarry Smith 
759a7e14dcfSSatish Balay   PetscFunctionBegin;
760441846f8SBarry Smith   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
761a7e14dcfSSatish Balay   PetscValidHeaderSpecific(X, VEC_CLASSID,2);
762a7e14dcfSSatish Balay   PetscCheckSameComm(tao,1,X,2);
763*3c859ba3SBarry Smith   PetscCheck(tao->ops->computejacobianequality,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Must call TaoSetJacobianEquality() first");
764a7e14dcfSSatish Balay   ++tao->njac_equality;
7658860a134SJunchao Zhang   ierr = VecLockReadPush(X);CHKERRQ(ierr);
7660ebee16dSLisandro Dalcin   ierr = PetscLogEventBegin(TAO_JacobianEval,tao,X,J,Jpre);CHKERRQ(ierr);
767441846f8SBarry Smith   PetscStackPush("Tao user Jacobian(equality) function");
768ffad9901SBarry Smith   ierr = (*tao->ops->computejacobianequality)(tao,X,J,Jpre,tao->user_jac_equalityP);CHKERRQ(ierr);
769a7e14dcfSSatish Balay   PetscStackPop;
7700ebee16dSLisandro Dalcin   ierr = PetscLogEventEnd(TAO_JacobianEval,tao,X,J,Jpre);CHKERRQ(ierr);
7718860a134SJunchao Zhang   ierr = VecLockReadPop(X);CHKERRQ(ierr);
772a7e14dcfSSatish Balay   PetscFunctionReturn(0);
773a7e14dcfSSatish Balay }
774a7e14dcfSSatish Balay 
775a7e14dcfSSatish Balay /*@C
776a7e14dcfSSatish Balay    TaoComputeJacobianInequality - Computes the Jacobian matrix that has been
777a7e14dcfSSatish Balay    set with TaoSetJacobianInequalityRoutine().
778a7e14dcfSSatish Balay 
779441846f8SBarry Smith    Collective on Tao
780a7e14dcfSSatish Balay 
781a7e14dcfSSatish Balay    Input Parameters:
782f4c1ad5cSStefano Zampini +  tao - the Tao solver context
783f4c1ad5cSStefano Zampini -  X   - input vector
784a7e14dcfSSatish Balay 
785a7e14dcfSSatish Balay    Output Parameters:
786f4c1ad5cSStefano Zampini +  J    - Jacobian matrix
787f4c1ad5cSStefano Zampini -  Jpre - Preconditioning matrix
788a7e14dcfSSatish Balay 
789a7e14dcfSSatish Balay    Notes:
790a7e14dcfSSatish Balay    Most users should not need to explicitly call this routine, as it
791a7e14dcfSSatish Balay    is used internally within the minimization solvers.
792a7e14dcfSSatish Balay 
793a7e14dcfSSatish Balay    Level: developer
794a7e14dcfSSatish Balay 
795a7e14dcfSSatish Balay .seealso:  TaoComputeObjective(), TaoComputeObjectiveAndGradient(), TaoSetJacobianStateRoutine(), TaoComputeJacobianDesign(), TaoSetStateDesignIS()
796a7e14dcfSSatish Balay @*/
797ffad9901SBarry Smith PetscErrorCode TaoComputeJacobianInequality(Tao tao, Vec X, Mat J, Mat Jpre)
798a7e14dcfSSatish Balay {
799a7e14dcfSSatish Balay   PetscErrorCode ierr;
80087f595a5SBarry Smith 
801a7e14dcfSSatish Balay   PetscFunctionBegin;
802441846f8SBarry Smith   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
803a7e14dcfSSatish Balay   PetscValidHeaderSpecific(X, VEC_CLASSID,2);
804a7e14dcfSSatish Balay   PetscCheckSameComm(tao,1,X,2);
805*3c859ba3SBarry Smith   PetscCheck(tao->ops->computejacobianinequality,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Must call TaoSetJacobianInequality() first");
806a7e14dcfSSatish Balay   ++tao->njac_inequality;
8078860a134SJunchao Zhang   ierr = VecLockReadPush(X);CHKERRQ(ierr);
8080ebee16dSLisandro Dalcin   ierr = PetscLogEventBegin(TAO_JacobianEval,tao,X,J,Jpre);CHKERRQ(ierr);
809441846f8SBarry Smith   PetscStackPush("Tao user Jacobian(inequality) function");
810ffad9901SBarry Smith   ierr = (*tao->ops->computejacobianinequality)(tao,X,J,Jpre,tao->user_jac_inequalityP);CHKERRQ(ierr);
811a7e14dcfSSatish Balay   PetscStackPop;
8120ebee16dSLisandro Dalcin   ierr = PetscLogEventEnd(TAO_JacobianEval,tao,X,J,Jpre);CHKERRQ(ierr);
8138860a134SJunchao Zhang   ierr = VecLockReadPop(X);CHKERRQ(ierr);
814a7e14dcfSSatish Balay   PetscFunctionReturn(0);
815a7e14dcfSSatish Balay }
816a7e14dcfSSatish Balay 
817a7e14dcfSSatish Balay /*@C
818a7e14dcfSSatish Balay    TaoSetJacobianEqualityRoutine - Sets the function to compute the Jacobian
819a7e14dcfSSatish Balay    (and its inverse) of the constraint function with respect to the equality variables.
820a7e14dcfSSatish Balay    Used only for pde-constrained optimization.
821a7e14dcfSSatish Balay 
822441846f8SBarry Smith    Logically collective on Tao
823a7e14dcfSSatish Balay 
824a7e14dcfSSatish Balay    Input Parameters:
825441846f8SBarry Smith +  tao  - the Tao context
826a7e14dcfSSatish Balay .  J    - Matrix used for the jacobian
827a7e14dcfSSatish Balay .  Jpre - Matrix that will be used operated on by PETSc preconditioner, can be same as J.
828f4c1ad5cSStefano Zampini .  func - Jacobian evaluation routine
829a7e14dcfSSatish Balay -  ctx  - [optional] user-defined context for private data for the
8306c23d075SBarry Smith           Jacobian evaluation routine (may be NULL)
831a7e14dcfSSatish Balay 
832f4c1ad5cSStefano Zampini    Calling sequence of func:
833f4c1ad5cSStefano Zampini $    func(Tao tao,Vec x,Mat J,Mat Jpre,void *ctx);
834a7e14dcfSSatish Balay 
835441846f8SBarry Smith +  tao  - the Tao  context
836a7e14dcfSSatish Balay .  x    - input vector
837a7e14dcfSSatish Balay .  J    - Jacobian matrix
838a7e14dcfSSatish Balay .  Jpre - preconditioner matrix, usually the same as J
839a7e14dcfSSatish Balay -  ctx  - [optional] user-defined Jacobian context
840a7e14dcfSSatish Balay 
841a7e14dcfSSatish Balay    Level: intermediate
842f4c1ad5cSStefano Zampini 
843f4c1ad5cSStefano Zampini .seealso: TaoComputeJacobianEquality(), TaoSetJacobianDesignRoutine(), TaoSetEqualityDesignIS()
844a7e14dcfSSatish Balay @*/
845ffad9901SBarry Smith PetscErrorCode TaoSetJacobianEqualityRoutine(Tao tao, Mat J, Mat Jpre, PetscErrorCode (*func)(Tao, Vec, Mat, Mat, void*), void *ctx)
846a7e14dcfSSatish Balay {
847a7e14dcfSSatish Balay   PetscErrorCode ierr;
84845cf516eSBarry Smith 
849a7e14dcfSSatish Balay   PetscFunctionBegin;
850441846f8SBarry Smith   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
851a7e14dcfSSatish Balay   if (J) {
852a7e14dcfSSatish Balay     PetscValidHeaderSpecific(J,MAT_CLASSID,2);
853a7e14dcfSSatish Balay     PetscCheckSameComm(tao,1,J,2);
854a7e14dcfSSatish Balay   }
855a7e14dcfSSatish Balay   if (Jpre) {
856a7e14dcfSSatish Balay     PetscValidHeaderSpecific(Jpre,MAT_CLASSID,3);
857a7e14dcfSSatish Balay     PetscCheckSameComm(tao,1,Jpre,3);
858a7e14dcfSSatish Balay   }
859a7e14dcfSSatish Balay   if (ctx) {
860a7e14dcfSSatish Balay     tao->user_jac_equalityP = ctx;
861a7e14dcfSSatish Balay   }
862a7e14dcfSSatish Balay   if (func) {
863a7e14dcfSSatish Balay     tao->ops->computejacobianequality = func;
864a7e14dcfSSatish Balay   }
865a7e14dcfSSatish Balay   if (J) {
866a7e14dcfSSatish Balay     ierr = PetscObjectReference((PetscObject)J);CHKERRQ(ierr);
86745cf516eSBarry Smith     ierr = MatDestroy(&tao->jacobian_equality);CHKERRQ(ierr);
868a7e14dcfSSatish Balay     tao->jacobian_equality = J;
869a7e14dcfSSatish Balay   }
870a7e14dcfSSatish Balay   if (Jpre) {
871a7e14dcfSSatish Balay     ierr = PetscObjectReference((PetscObject)Jpre);CHKERRQ(ierr);
87245cf516eSBarry Smith     ierr = MatDestroy(&tao->jacobian_equality_pre);CHKERRQ(ierr);
873a7e14dcfSSatish Balay     tao->jacobian_equality_pre=Jpre;
874a7e14dcfSSatish Balay   }
875a7e14dcfSSatish Balay   PetscFunctionReturn(0);
876a7e14dcfSSatish Balay }
877a7e14dcfSSatish Balay 
878a7e14dcfSSatish Balay /*@C
879a7e14dcfSSatish Balay    TaoSetJacobianInequalityRoutine - Sets the function to compute the Jacobian
880a7e14dcfSSatish Balay    (and its inverse) of the constraint function with respect to the inequality variables.
881a7e14dcfSSatish Balay    Used only for pde-constrained optimization.
882a7e14dcfSSatish Balay 
883441846f8SBarry Smith    Logically collective on Tao
884a7e14dcfSSatish Balay 
885a7e14dcfSSatish Balay    Input Parameters:
886441846f8SBarry Smith +  tao  - the Tao context
887a7e14dcfSSatish Balay .  J    - Matrix used for the jacobian
888a7e14dcfSSatish Balay .  Jpre - Matrix that will be used operated on by PETSc preconditioner, can be same as J.
889f4c1ad5cSStefano Zampini .  func - Jacobian evaluation routine
890a7e14dcfSSatish Balay -  ctx  - [optional] user-defined context for private data for the
8916c23d075SBarry Smith           Jacobian evaluation routine (may be NULL)
892a7e14dcfSSatish Balay 
893f4c1ad5cSStefano Zampini    Calling sequence of func:
894f4c1ad5cSStefano Zampini $    func(Tao tao,Vec x,Mat J,Mat Jpre,void *ctx);
895a7e14dcfSSatish Balay 
896441846f8SBarry Smith +  tao  - the Tao  context
897a7e14dcfSSatish Balay .  x    - input vector
898a7e14dcfSSatish Balay .  J    - Jacobian matrix
899a7e14dcfSSatish Balay .  Jpre - preconditioner matrix, usually the same as J
900a7e14dcfSSatish Balay -  ctx  - [optional] user-defined Jacobian context
901a7e14dcfSSatish Balay 
902a7e14dcfSSatish Balay    Level: intermediate
903f4c1ad5cSStefano Zampini 
904f4c1ad5cSStefano Zampini .seealso: TaoComputeJacobianInequality(), TaoSetJacobianDesignRoutine(), TaoSetInequalityDesignIS()
905a7e14dcfSSatish Balay @*/
906ffad9901SBarry Smith PetscErrorCode TaoSetJacobianInequalityRoutine(Tao tao, Mat J, Mat Jpre, PetscErrorCode (*func)(Tao, Vec, Mat, Mat,void*), void *ctx)
907a7e14dcfSSatish Balay {
908a7e14dcfSSatish Balay   PetscErrorCode ierr;
909f4c1ad5cSStefano Zampini 
910a7e14dcfSSatish Balay   PetscFunctionBegin;
911441846f8SBarry Smith   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
912a7e14dcfSSatish Balay   if (J) {
913a7e14dcfSSatish Balay     PetscValidHeaderSpecific(J,MAT_CLASSID,2);
914a7e14dcfSSatish Balay     PetscCheckSameComm(tao,1,J,2);
915a7e14dcfSSatish Balay   }
916a7e14dcfSSatish Balay   if (Jpre) {
917a7e14dcfSSatish Balay     PetscValidHeaderSpecific(Jpre,MAT_CLASSID,3);
918a7e14dcfSSatish Balay     PetscCheckSameComm(tao,1,Jpre,3);
919a7e14dcfSSatish Balay   }
920a7e14dcfSSatish Balay   if (ctx) {
921a7e14dcfSSatish Balay     tao->user_jac_inequalityP = ctx;
922a7e14dcfSSatish Balay   }
923a7e14dcfSSatish Balay   if (func) {
924a7e14dcfSSatish Balay     tao->ops->computejacobianinequality = func;
925a7e14dcfSSatish Balay   }
926a7e14dcfSSatish Balay   if (J) {
927a7e14dcfSSatish Balay     ierr = PetscObjectReference((PetscObject)J);CHKERRQ(ierr);
92845cf516eSBarry Smith     ierr = MatDestroy(&tao->jacobian_inequality);CHKERRQ(ierr);
929a7e14dcfSSatish Balay     tao->jacobian_inequality = J;
930a7e14dcfSSatish Balay   }
931a7e14dcfSSatish Balay   if (Jpre) {
932a7e14dcfSSatish Balay     ierr = PetscObjectReference((PetscObject)Jpre);CHKERRQ(ierr);
93345cf516eSBarry Smith     ierr = MatDestroy(&tao->jacobian_inequality_pre);CHKERRQ(ierr);
934a7e14dcfSSatish Balay     tao->jacobian_inequality_pre=Jpre;
935a7e14dcfSSatish Balay   }
936a7e14dcfSSatish Balay   PetscFunctionReturn(0);
937a7e14dcfSSatish Balay }
938