Actual source code: taosolver_hj.c
1: #include <petsc/private/taoimpl.h>
3: /*@C
4: TaoSetHessian - Sets the function to compute the Hessian as well as the location to store the matrix.
6: Logically collective on tao
8: Input Parameters:
9: + tao - the Tao context
10: . H - Matrix used for the hessian
11: . Hpre - Matrix that will be used operated on by preconditioner, can be same as H
12: . func - Hessian evaluation routine
13: - ctx - [optional] user-defined context for private data for the
14: Hessian evaluation routine (may be NULL)
16: Calling sequence of func:
17: $ func(Tao tao,Vec x,Mat H,Mat Hpre,void *ctx);
19: + tao - the Tao context
20: . x - input vector
21: . H - Hessian matrix
22: . Hpre - preconditioner matrix, usually the same as H
23: - ctx - [optional] user-defined Hessian context
25: Level: beginner
27: .seealso: `Tao`, `TaoTypes`, `TaoSetObjective()`, `TaoSetGradient()`, `TaoSetObjectiveAndGradient()`, `TaoGetHessian()`
28: @*/
29: PetscErrorCode TaoSetHessian(Tao tao, Mat H, Mat Hpre, PetscErrorCode (*func)(Tao, Vec, Mat, Mat, void *), void *ctx)
30: {
32: if (H) {
35: }
36: if (Hpre) {
39: }
40: if (ctx) tao->user_hessP = ctx;
41: if (func) tao->ops->computehessian = func;
42: if (H) {
43: PetscObjectReference((PetscObject)H);
44: MatDestroy(&tao->hessian);
45: tao->hessian = H;
46: }
47: if (Hpre) {
48: PetscObjectReference((PetscObject)Hpre);
49: MatDestroy(&tao->hessian_pre);
50: tao->hessian_pre = Hpre;
51: }
52: return 0;
53: }
55: /*@C
56: TaoGetHessian - Gets the function to compute the Hessian as well as the location to store the matrix.
58: Not collective
60: Input Parameter:
61: . tao - the Tao context
63: OutputParameters:
64: + H - Matrix used for the hessian
65: . Hpre - Matrix that will be used operated on by preconditioner, can be the same as H
66: . func - Hessian evaluation routine
67: - ctx - user-defined context for private data for the Hessian evaluation routine
69: Calling sequence of func:
70: $ func(Tao tao,Vec x,Mat H,Mat Hpre,void *ctx);
72: + tao - the Tao context
73: . x - input vector
74: . H - Hessian matrix
75: . Hpre - preconditioner matrix, usually the same as H
76: - ctx - [optional] user-defined Hessian context
78: Level: beginner
80: .seealso: `Tao`, TaoType`, `TaoGetObjective()`, `TaoGetGradient()`, `TaoGetObjectiveAndGradient()`, `TaoSetHessian()`
81: @*/
82: PetscErrorCode TaoGetHessian(Tao tao, Mat *H, Mat *Hpre, PetscErrorCode (**func)(Tao, Vec, Mat, Mat, void *), void **ctx)
83: {
85: if (H) *H = tao->hessian;
86: if (Hpre) *Hpre = tao->hessian_pre;
87: if (ctx) *ctx = tao->user_hessP;
88: if (func) *func = tao->ops->computehessian;
89: return 0;
90: }
92: PetscErrorCode TaoTestHessian(Tao tao)
93: {
94: Mat A, B, C, D, hessian;
95: Vec x = tao->solution;
96: PetscReal nrm, gnorm;
97: PetscReal threshold = 1.e-5;
98: PetscInt m, n, M, N;
99: PetscBool complete_print = PETSC_FALSE, test = PETSC_FALSE, flg;
100: PetscViewer viewer, mviewer;
101: MPI_Comm comm;
102: PetscInt tabs;
103: static PetscBool directionsprinted = PETSC_FALSE;
104: PetscViewerFormat format;
106: PetscObjectOptionsBegin((PetscObject)tao);
107: PetscOptionsName("-tao_test_hessian", "Compare hand-coded and finite difference Hessians", "None", &test);
108: PetscOptionsReal("-tao_test_hessian", "Threshold for element difference between hand-coded and finite difference being meaningful", "None", threshold, &threshold, NULL);
109: PetscOptionsViewer("-tao_test_hessian_view", "View difference between hand-coded and finite difference Hessians element entries", "None", &mviewer, &format, &complete_print);
110: PetscOptionsEnd();
111: if (!test) return 0;
113: PetscObjectGetComm((PetscObject)tao, &comm);
114: PetscViewerASCIIGetStdout(comm, &viewer);
115: PetscViewerASCIIGetTab(viewer, &tabs);
116: PetscViewerASCIISetTab(viewer, ((PetscObject)tao)->tablevel);
117: PetscViewerASCIIPrintf(viewer, " ---------- Testing Hessian -------------\n");
118: if (!complete_print && !directionsprinted) {
119: PetscViewerASCIIPrintf(viewer, " Run with -tao_test_hessian_view and optionally -tao_test_hessian <threshold> to show difference\n");
120: PetscViewerASCIIPrintf(viewer, " of hand-coded and finite difference Hessian entries greater than <threshold>.\n");
121: }
122: if (!directionsprinted) {
123: PetscViewerASCIIPrintf(viewer, " Testing hand-coded Hessian, if (for double precision runs) ||J - Jfd||_F/||J||_F is\n");
124: PetscViewerASCIIPrintf(viewer, " O(1.e-8), the hand-coded Hessian is probably correct.\n");
125: directionsprinted = PETSC_TRUE;
126: }
127: if (complete_print) PetscViewerPushFormat(mviewer, format);
129: PetscObjectTypeCompare((PetscObject)tao->hessian, MATMFFD, &flg);
130: if (!flg) hessian = tao->hessian;
131: else hessian = tao->hessian_pre;
133: while (hessian) {
134: PetscObjectBaseTypeCompareAny((PetscObject)hessian, &flg, MATSEQAIJ, MATMPIAIJ, MATSEQDENSE, MATMPIDENSE, MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPIBAIJ, "");
135: if (flg) {
136: A = hessian;
137: PetscObjectReference((PetscObject)A);
138: } else {
139: MatComputeOperator(hessian, MATAIJ, &A);
140: }
142: MatCreate(PetscObjectComm((PetscObject)A), &B);
143: MatGetSize(A, &M, &N);
144: MatGetLocalSize(A, &m, &n);
145: MatSetSizes(B, m, n, M, N);
146: MatSetType(B, ((PetscObject)A)->type_name);
147: MatSetUp(B);
148: MatSetOption(B, MAT_NEW_NONZERO_ALLOCATION_ERR, PETSC_FALSE);
150: TaoDefaultComputeHessian(tao, x, B, B, NULL);
152: MatDuplicate(B, MAT_COPY_VALUES, &D);
153: MatAYPX(D, -1.0, A, DIFFERENT_NONZERO_PATTERN);
154: MatNorm(D, NORM_FROBENIUS, &nrm);
155: MatNorm(A, NORM_FROBENIUS, &gnorm);
156: MatDestroy(&D);
157: if (!gnorm) gnorm = 1; /* just in case */
158: PetscViewerASCIIPrintf(viewer, " ||H - Hfd||_F/||H||_F = %g, ||H - Hfd||_F = %g\n", (double)(nrm / gnorm), (double)nrm);
160: if (complete_print) {
161: PetscViewerASCIIPrintf(viewer, " Hand-coded Hessian ----------\n");
162: MatView(A, mviewer);
163: PetscViewerASCIIPrintf(viewer, " Finite difference Hessian ----------\n");
164: MatView(B, mviewer);
165: }
167: if (complete_print) {
168: PetscInt Istart, Iend, *ccols, bncols, cncols, j, row;
169: PetscScalar *cvals;
170: const PetscInt *bcols;
171: const PetscScalar *bvals;
173: MatAYPX(B, -1.0, A, DIFFERENT_NONZERO_PATTERN);
174: MatCreate(PetscObjectComm((PetscObject)A), &C);
175: MatSetSizes(C, m, n, M, N);
176: MatSetType(C, ((PetscObject)A)->type_name);
177: MatSetUp(C);
178: MatSetOption(C, MAT_NEW_NONZERO_ALLOCATION_ERR, PETSC_FALSE);
179: MatGetOwnershipRange(B, &Istart, &Iend);
181: for (row = Istart; row < Iend; row++) {
182: MatGetRow(B, row, &bncols, &bcols, &bvals);
183: PetscMalloc2(bncols, &ccols, bncols, &cvals);
184: for (j = 0, cncols = 0; j < bncols; j++) {
185: if (PetscAbsScalar(bvals[j]) > threshold) {
186: ccols[cncols] = bcols[j];
187: cvals[cncols] = bvals[j];
188: cncols += 1;
189: }
190: }
191: if (cncols) MatSetValues(C, 1, &row, cncols, ccols, cvals, INSERT_VALUES);
192: MatRestoreRow(B, row, &bncols, &bcols, &bvals);
193: PetscFree2(ccols, cvals);
194: }
195: MatAssemblyBegin(C, MAT_FINAL_ASSEMBLY);
196: MatAssemblyEnd(C, MAT_FINAL_ASSEMBLY);
197: PetscViewerASCIIPrintf(viewer, " Finite-difference minus hand-coded Hessian with tolerance %g ----------\n", (double)threshold);
198: MatView(C, mviewer);
199: MatDestroy(&C);
200: }
201: MatDestroy(&A);
202: MatDestroy(&B);
204: if (hessian != tao->hessian_pre) {
205: hessian = tao->hessian_pre;
206: PetscViewerASCIIPrintf(viewer, " ---------- Testing Hessian for preconditioner -------------\n");
207: } else hessian = NULL;
208: }
209: if (complete_print) {
210: PetscViewerPopFormat(mviewer);
211: PetscViewerDestroy(&mviewer);
212: }
213: PetscViewerASCIISetTab(viewer, tabs);
214: return 0;
215: }
217: /*@C
218: TaoComputeHessian - Computes the Hessian matrix that has been
219: set with `TaoSetHessian()`.
221: Collective on tao
223: Input Parameters:
224: + tao - the Tao solver context
225: - X - input vector
227: Output Parameters:
228: + H - Hessian matrix
229: - Hpre - Preconditioning matrix
231: Options Database Keys:
232: + -tao_test_hessian - compare the user provided Hessian with one compute via finite differences to check for errors
233: . -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
234: - -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
236: Notes:
237: Most users should not need to explicitly call this routine, as it
238: is used internally within the minimization solvers.
240: `TaoComputeHessian()` is typically used within optimization algorithms,
241: so most users would not generally call this routine
242: themselves.
244: Developer Note:
245: The Hessian test mechanism follows `SNESTestJacobian()`.
247: Level: developer
249: .seealso: `Tao`, `TaoComputeObjective()`, `TaoComputeObjectiveAndGradient()`, `TaoSetHessian()`
250: @*/
251: PetscErrorCode TaoComputeHessian(Tao tao, Vec X, Mat H, Mat Hpre)
252: {
256: ++tao->nhess;
257: VecLockReadPush(X);
258: PetscLogEventBegin(TAO_HessianEval, tao, X, H, Hpre);
259: PetscCallBack("Tao callback Hessian", (*tao->ops->computehessian)(tao, X, H, Hpre, tao->user_hessP));
260: PetscLogEventEnd(TAO_HessianEval, tao, X, H, Hpre);
261: VecLockReadPop(X);
263: TaoTestHessian(tao);
264: return 0;
265: }
267: /*@C
268: TaoComputeJacobian - Computes the Jacobian matrix that has been
269: set with TaoSetJacobianRoutine().
271: Collective on tao
273: Input Parameters:
274: + tao - the Tao solver context
275: - X - input vector
277: Output Parameters:
278: + J - Jacobian matrix
279: - Jpre - Preconditioning matrix
281: Notes:
282: Most users should not need to explicitly call this routine, as it
283: is used internally within the minimization solvers.
285: `TaoComputeJacobian()` is typically used within minimization
286: implementations, so most users would not generally call this routine
287: themselves.
289: Level: developer
291: .seealso: `TaoComputeObjective()`, `TaoComputeObjectiveAndGradient()`, `TaoSetJacobianRoutine()`
292: @*/
293: PetscErrorCode TaoComputeJacobian(Tao tao, Vec X, Mat J, Mat Jpre)
294: {
298: ++tao->njac;
299: VecLockReadPush(X);
300: PetscLogEventBegin(TAO_JacobianEval, tao, X, J, Jpre);
301: PetscCallBack("Tao callback Jacobian", (*tao->ops->computejacobian)(tao, X, J, Jpre, tao->user_jacP));
302: PetscLogEventEnd(TAO_JacobianEval, tao, X, J, Jpre);
303: VecLockReadPop(X);
304: return 0;
305: }
307: /*@C
308: TaoComputeResidualJacobian - Computes the least-squares residual Jacobian matrix that has been
309: set with `TaoSetJacobianResidual()`.
311: Collective on tao
313: Input Parameters:
314: + tao - the Tao solver context
315: - X - input vector
317: Output Parameters:
318: + J - Jacobian matrix
319: - Jpre - Preconditioning matrix
321: Notes:
322: Most users should not need to explicitly call this routine, as it
323: is used internally within the minimization solvers.
325: `TaoComputeResidualJacobian()` is typically used within least-squares
326: implementations, so most users would not generally call this routine
327: themselves.
329: Level: developer
331: .seealso: `Tao`, `TaoComputeResidual()`, `TaoSetJacobianResidual()`
332: @*/
333: PetscErrorCode TaoComputeResidualJacobian(Tao tao, Vec X, Mat J, Mat Jpre)
334: {
338: ++tao->njac;
339: VecLockReadPush(X);
340: PetscLogEventBegin(TAO_JacobianEval, tao, X, J, Jpre);
341: PetscCallBack("Tao callback least-squares residual Jacobian", (*tao->ops->computeresidualjacobian)(tao, X, J, Jpre, tao->user_lsjacP));
342: PetscLogEventEnd(TAO_JacobianEval, tao, X, J, Jpre);
343: VecLockReadPop(X);
344: return 0;
345: }
347: /*@C
348: TaoComputeJacobianState - Computes the Jacobian matrix that has been
349: set with `TaoSetJacobianStateRoutine()`.
351: Collective on tao
353: Input Parameters:
354: + tao - the Tao solver context
355: - X - input vector
357: Output Parameters:
358: + J - Jacobian matrix
359: . Jpre - Preconditioning matrix
360: - Jinv - unknown
362: Notes:
363: Most users should not need to explicitly call this routine, as it
364: is used internally within the optimization algorithms.
366: Level: developer
368: .seealso: `Tao`, `TaoComputeObjective()`, `TaoComputeObjectiveAndGradient()`, `TaoSetJacobianStateRoutine()`, `TaoComputeJacobianDesign()`, `TaoSetStateDesignIS()`
369: @*/
370: PetscErrorCode TaoComputeJacobianState(Tao tao, Vec X, Mat J, Mat Jpre, Mat Jinv)
371: {
375: ++tao->njac_state;
376: VecLockReadPush(X);
377: PetscLogEventBegin(TAO_JacobianEval, tao, X, J, Jpre);
378: PetscCallBack("Tao callback Jacobian(state)", (*tao->ops->computejacobianstate)(tao, X, J, Jpre, Jinv, tao->user_jac_stateP));
379: PetscLogEventEnd(TAO_JacobianEval, tao, X, J, Jpre);
380: VecLockReadPop(X);
381: return 0;
382: }
384: /*@C
385: TaoComputeJacobianDesign - Computes the Jacobian matrix that has been
386: set with `TaoSetJacobianDesignRoutine()`.
388: Collective on tao
390: Input Parameters:
391: + tao - the Tao solver context
392: - X - input vector
394: Output Parameters:
395: . J - Jacobian matrix
397: Notes:
398: Most users should not need to explicitly call this routine, as it
399: is used internally within the optimization algorithms.
401: Level: developer
403: .seealso: `Tao`, `TaoComputeObjective()`, `TaoComputeObjectiveAndGradient()`, `TaoSetJacobianDesignRoutine()`, `TaoComputeJacobianDesign()`, `TaoSetStateDesignIS()`
404: @*/
405: PetscErrorCode TaoComputeJacobianDesign(Tao tao, Vec X, Mat J)
406: {
410: ++tao->njac_design;
411: VecLockReadPush(X);
412: PetscLogEventBegin(TAO_JacobianEval, tao, X, J, NULL);
413: PetscCallBack("Tao callback Jacobian(design)", (*tao->ops->computejacobiandesign)(tao, X, J, tao->user_jac_designP));
414: PetscLogEventEnd(TAO_JacobianEval, tao, X, J, NULL);
415: VecLockReadPop(X);
416: return 0;
417: }
419: /*@C
420: TaoSetJacobianRoutine - Sets the function to compute the Jacobian as well as the location to store the matrix.
422: Logically collective on tao
424: Input Parameters:
425: + tao - the Tao context
426: . J - Matrix used for the jacobian
427: . Jpre - Matrix that will be used operated on by preconditioner, can be same as J
428: . func - Jacobian evaluation routine
429: - ctx - [optional] user-defined context for private data for the
430: Jacobian evaluation routine (may be NULL)
432: Calling sequence of func:
433: $ func(Tao tao,Vec x,Mat J,Mat Jpre,void *ctx);
435: + tao - the Tao context
436: . x - input vector
437: . J - Jacobian matrix
438: . Jpre - preconditioning matrix, usually the same as J
439: - ctx - [optional] user-defined Jacobian context
441: Level: intermediate
443: .seealso: `Tao`, `TaoSetGradient()`, `TaoSetObjective()`
444: @*/
445: PetscErrorCode TaoSetJacobianRoutine(Tao tao, Mat J, Mat Jpre, PetscErrorCode (*func)(Tao, Vec, Mat, Mat, void *), void *ctx)
446: {
448: if (J) {
451: }
452: if (Jpre) {
455: }
456: if (ctx) tao->user_jacP = ctx;
457: if (func) tao->ops->computejacobian = func;
458: if (J) {
459: PetscObjectReference((PetscObject)J);
460: MatDestroy(&tao->jacobian);
461: tao->jacobian = J;
462: }
463: if (Jpre) {
464: PetscObjectReference((PetscObject)Jpre);
465: MatDestroy(&tao->jacobian_pre);
466: tao->jacobian_pre = Jpre;
467: }
468: return 0;
469: }
471: /*@C
472: TaoSetJacobianResidualRoutine - Sets the function to compute the least-squares residual Jacobian as well as the
473: location to store the matrix.
475: Logically collective on tao
477: Input Parameters:
478: + tao - the Tao context
479: . J - Matrix used for the jacobian
480: . Jpre - Matrix that will be used operated on by preconditioner, can be same as J
481: . func - Jacobian evaluation routine
482: - ctx - [optional] user-defined context for private data for the
483: Jacobian evaluation routine (may be NULL)
485: Calling sequence of func:
486: $ func(Tao tao,Vec x,Mat J,Mat Jpre,void *ctx);
488: + tao - the Tao context
489: . x - input vector
490: . J - Jacobian matrix
491: . Jpre - preconditioning matrix, usually the same as J
492: - ctx - [optional] user-defined Jacobian context
494: Level: intermediate
496: .seealso: `Tao`, `TaoSetGradient()`, `TaoSetObjective()`
497: @*/
498: PetscErrorCode TaoSetJacobianResidualRoutine(Tao tao, Mat J, Mat Jpre, PetscErrorCode (*func)(Tao, Vec, Mat, Mat, void *), void *ctx)
499: {
501: if (J) {
504: }
505: if (Jpre) {
508: }
509: if (ctx) tao->user_lsjacP = ctx;
510: if (func) tao->ops->computeresidualjacobian = func;
511: if (J) {
512: PetscObjectReference((PetscObject)J);
513: MatDestroy(&tao->ls_jac);
514: tao->ls_jac = J;
515: }
516: if (Jpre) {
517: PetscObjectReference((PetscObject)Jpre);
518: MatDestroy(&tao->ls_jac_pre);
519: tao->ls_jac_pre = Jpre;
520: }
521: return 0;
522: }
524: /*@C
525: TaoSetJacobianStateRoutine - Sets the function to compute the Jacobian
526: (and its inverse) of the constraint function with respect to the state variables.
527: Used only for PDE-constrained optimization.
529: Logically collective on tao
531: Input Parameters:
532: + tao - the Tao context
533: . J - Matrix used for the jacobian
534: . Jpre - Matrix that will be used operated on by PETSc preconditioner, can be same as J. Only used if Jinv is NULL
535: . Jinv - [optional] Matrix used to apply the inverse of the state jacobian. Use NULL to default to PETSc KSP solvers to apply the inverse.
536: . func - Jacobian evaluation routine
537: - ctx - [optional] user-defined context for private data for the
538: Jacobian evaluation routine (may be NULL)
540: Calling sequence of func:
541: $ func(Tao tao,Vec x,Mat J,Mat Jpre,Mat Jinv,void *ctx);
543: + tao - the Tao context
544: . x - input vector
545: . J - Jacobian matrix
546: . Jpre - preconditioner matrix, usually the same as J
547: . Jinv - inverse of J
548: - ctx - [optional] user-defined Jacobian context
550: Level: intermediate
552: .seealso: `Tao`, `TaoComputeJacobianState()`, `TaoSetJacobianDesignRoutine()`, `TaoSetStateDesignIS()`
553: @*/
554: PetscErrorCode TaoSetJacobianStateRoutine(Tao tao, Mat J, Mat Jpre, Mat Jinv, PetscErrorCode (*func)(Tao, Vec, Mat, Mat, Mat, void *), void *ctx)
555: {
557: if (J) {
560: }
561: if (Jpre) {
564: }
565: if (Jinv) {
568: }
569: if (ctx) tao->user_jac_stateP = ctx;
570: if (func) tao->ops->computejacobianstate = func;
571: if (J) {
572: PetscObjectReference((PetscObject)J);
573: MatDestroy(&tao->jacobian_state);
574: tao->jacobian_state = J;
575: }
576: if (Jpre) {
577: PetscObjectReference((PetscObject)Jpre);
578: MatDestroy(&tao->jacobian_state_pre);
579: tao->jacobian_state_pre = Jpre;
580: }
581: if (Jinv) {
582: PetscObjectReference((PetscObject)Jinv);
583: MatDestroy(&tao->jacobian_state_inv);
584: tao->jacobian_state_inv = Jinv;
585: }
586: return 0;
587: }
589: /*@C
590: TaoSetJacobianDesignRoutine - Sets the function to compute the Jacobian of
591: the constraint function with respect to the design variables. Used only for
592: PDE-constrained optimization.
594: Logically collective on tao
596: Input Parameters:
597: + tao - the Tao context
598: . J - Matrix used for the jacobian
599: . func - Jacobian evaluation routine
600: - ctx - [optional] user-defined context for private data for the
601: Jacobian evaluation routine (may be NULL)
603: Calling sequence of func:
604: $ func(Tao tao,Vec x,Mat J,void *ctx);
606: + tao - the Tao context
607: . x - input vector
608: . J - Jacobian matrix
609: - ctx - [optional] user-defined Jacobian context
611: Level: intermediate
613: .seealso: `Tao`, `TaoComputeJacobianDesign()`, `TaoSetJacobianStateRoutine()`, `TaoSetStateDesignIS()`
614: @*/
615: PetscErrorCode TaoSetJacobianDesignRoutine(Tao tao, Mat J, PetscErrorCode (*func)(Tao, Vec, Mat, void *), void *ctx)
616: {
618: if (J) {
621: }
622: if (ctx) tao->user_jac_designP = ctx;
623: if (func) tao->ops->computejacobiandesign = func;
624: if (J) {
625: PetscObjectReference((PetscObject)J);
626: MatDestroy(&tao->jacobian_design);
627: tao->jacobian_design = J;
628: }
629: return 0;
630: }
632: /*@
633: TaoSetStateDesignIS - Indicate to the Tao which variables in the
634: solution vector are state variables and which are design. Only applies to
635: PDE-constrained optimization.
637: Logically Collective on Tao
639: Input Parameters:
640: + tao - The Tao context
641: . s_is - the index set corresponding to the state variables
642: - d_is - the index set corresponding to the design variables
644: Level: intermediate
646: .seealso: `Tao`, `TaoSetJacobianStateRoutine()`, `TaoSetJacobianDesignRoutine()`
647: @*/
648: PetscErrorCode TaoSetStateDesignIS(Tao tao, IS s_is, IS d_is)
649: {
650: PetscObjectReference((PetscObject)s_is);
651: ISDestroy(&tao->state_is);
652: tao->state_is = s_is;
653: PetscObjectReference((PetscObject)(d_is));
654: ISDestroy(&tao->design_is);
655: tao->design_is = d_is;
656: return 0;
657: }
659: /*@C
660: TaoComputeJacobianEquality - Computes the Jacobian matrix that has been
661: set with `TaoSetJacobianEqualityRoutine()`.
663: Collective on tao
665: Input Parameters:
666: + tao - the Tao solver context
667: - X - input vector
669: Output Parameters:
670: + J - Jacobian matrix
671: - Jpre - Preconditioning matrix
673: Notes:
674: Most users should not need to explicitly call this routine, as it
675: is used internally within the optimization algorithms.
677: Level: developer
679: .seealso: `TaoComputeObjective()`, `TaoComputeObjectiveAndGradient()`, `TaoSetJacobianStateRoutine()`, `TaoComputeJacobianDesign()`, `TaoSetStateDesignIS()`
680: @*/
681: PetscErrorCode TaoComputeJacobianEquality(Tao tao, Vec X, Mat J, Mat Jpre)
682: {
686: ++tao->njac_equality;
687: VecLockReadPush(X);
688: PetscLogEventBegin(TAO_JacobianEval, tao, X, J, Jpre);
689: PetscCallBack("Tao callback Jacobian(equality)", (*tao->ops->computejacobianequality)(tao, X, J, Jpre, tao->user_jac_equalityP));
690: PetscLogEventEnd(TAO_JacobianEval, tao, X, J, Jpre);
691: VecLockReadPop(X);
692: return 0;
693: }
695: /*@C
696: TaoComputeJacobianInequality - Computes the Jacobian matrix that has been
697: set with `TaoSetJacobianInequalityRoutine()`.
699: Collective on tao
701: Input Parameters:
702: + tao - the Tao solver context
703: - X - input vector
705: Output Parameters:
706: + J - Jacobian matrix
707: - Jpre - Preconditioning matrix
709: Notes:
710: Most users should not need to explicitly call this routine, as it
711: is used internally within the minimization solvers.
713: Level: developer
715: .seealso: `Tao`, `TaoComputeObjective()`, `TaoComputeObjectiveAndGradient()`, `TaoSetJacobianStateRoutine()`, `TaoComputeJacobianDesign()`, `TaoSetStateDesignIS()`
716: @*/
717: PetscErrorCode TaoComputeJacobianInequality(Tao tao, Vec X, Mat J, Mat Jpre)
718: {
722: ++tao->njac_inequality;
723: VecLockReadPush(X);
724: PetscLogEventBegin(TAO_JacobianEval, tao, X, J, Jpre);
725: PetscCallBack("Tao callback Jacobian (inequality)", (*tao->ops->computejacobianinequality)(tao, X, J, Jpre, tao->user_jac_inequalityP));
726: PetscLogEventEnd(TAO_JacobianEval, tao, X, J, Jpre);
727: VecLockReadPop(X);
728: return 0;
729: }
731: /*@C
732: TaoSetJacobianEqualityRoutine - Sets the function to compute the Jacobian
733: (and its inverse) of the constraint function with respect to the equality variables.
734: Used only for PDE-constrained optimization.
736: Logically collective on tao
738: Input Parameters:
739: + tao - the Tao context
740: . J - Matrix used for the jacobian
741: . Jpre - Matrix that will be used operated on by PETSc preconditioner, can be same as J.
742: . func - Jacobian evaluation routine
743: - ctx - [optional] user-defined context for private data for the
744: Jacobian evaluation routine (may be NULL)
746: Calling sequence of func:
747: $ func(Tao tao,Vec x,Mat J,Mat Jpre,void *ctx);
749: + tao - the Tao context
750: . x - input vector
751: . J - Jacobian matrix
752: . Jpre - preconditioner matrix, usually the same as J
753: - ctx - [optional] user-defined Jacobian context
755: Level: intermediate
757: .seealso: `Tao`, `TaoComputeJacobianEquality()`, `TaoSetJacobianDesignRoutine()`, `TaoSetEqualityDesignIS()`
758: @*/
759: PetscErrorCode TaoSetJacobianEqualityRoutine(Tao tao, Mat J, Mat Jpre, PetscErrorCode (*func)(Tao, Vec, Mat, Mat, void *), void *ctx)
760: {
762: if (J) {
765: }
766: if (Jpre) {
769: }
770: if (ctx) tao->user_jac_equalityP = ctx;
771: if (func) tao->ops->computejacobianequality = func;
772: if (J) {
773: PetscObjectReference((PetscObject)J);
774: MatDestroy(&tao->jacobian_equality);
775: tao->jacobian_equality = J;
776: }
777: if (Jpre) {
778: PetscObjectReference((PetscObject)Jpre);
779: MatDestroy(&tao->jacobian_equality_pre);
780: tao->jacobian_equality_pre = Jpre;
781: }
782: return 0;
783: }
785: /*@C
786: TaoSetJacobianInequalityRoutine - Sets the function to compute the Jacobian
787: (and its inverse) of the constraint function with respect to the inequality variables.
788: Used only for PDE-constrained optimization.
790: Logically collective on tao
792: Input Parameters:
793: + tao - the Tao context
794: . J - Matrix used for the jacobian
795: . Jpre - Matrix that will be used operated on by PETSc preconditioner, can be same as J.
796: . func - Jacobian evaluation routine
797: - ctx - [optional] user-defined context for private data for the
798: Jacobian evaluation routine (may be NULL)
800: Calling sequence of func:
801: $ func(Tao tao,Vec x,Mat J,Mat Jpre,void *ctx);
803: + tao - the Tao context
804: . x - input vector
805: . J - Jacobian matrix
806: . Jpre - preconditioner matrix, usually the same as J
807: - ctx - [optional] user-defined Jacobian context
809: Level: intermediate
811: .seealso: `Tao`, `TaoComputeJacobianInequality()`, `TaoSetJacobianDesignRoutine()`, `TaoSetInequalityDesignIS()`
812: @*/
813: PetscErrorCode TaoSetJacobianInequalityRoutine(Tao tao, Mat J, Mat Jpre, PetscErrorCode (*func)(Tao, Vec, Mat, Mat, void *), void *ctx)
814: {
816: if (J) {
819: }
820: if (Jpre) {
823: }
824: if (ctx) tao->user_jac_inequalityP = ctx;
825: if (func) tao->ops->computejacobianinequality = func;
826: if (J) {
827: PetscObjectReference((PetscObject)J);
828: MatDestroy(&tao->jacobian_inequality);
829: tao->jacobian_inequality = J;
830: }
831: if (Jpre) {
832: PetscObjectReference((PetscObject)Jpre);
833: MatDestroy(&tao->jacobian_inequality_pre);
834: tao->jacobian_inequality_pre = Jpre;
835: }
836: return 0;
837: }