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
8: Input Parameters:
9: + tao - the `Tao` context
10: . H - Matrix used for the hessian
11: . Hpre - Matrix that will be used to construct the 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 - matrix used to construct the preconditioner, usually the same as `H`
23: - ctx - [optional] user-defined Hessian context
25: Level: beginner
27: .seealso: [](chapter_tao), `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: {
31: PetscFunctionBegin;
33: if (H) {
35: PetscCheckSameComm(tao, 1, H, 2);
36: }
37: if (Hpre) {
39: PetscCheckSameComm(tao, 1, Hpre, 3);
40: }
41: if (ctx) tao->user_hessP = ctx;
42: if (func) tao->ops->computehessian = func;
43: if (H) {
44: PetscCall(PetscObjectReference((PetscObject)H));
45: PetscCall(MatDestroy(&tao->hessian));
46: tao->hessian = H;
47: }
48: if (Hpre) {
49: PetscCall(PetscObjectReference((PetscObject)Hpre));
50: PetscCall(MatDestroy(&tao->hessian_pre));
51: tao->hessian_pre = Hpre;
52: }
53: PetscFunctionReturn(PETSC_SUCCESS);
54: }
56: /*@C
57: TaoGetHessian - Gets the function to compute the Hessian as well as the location to store the matrix.
59: Not collective
61: Input Parameter:
62: . tao - the `Tao` context
64: OutputParameters:
65: + H - Matrix used for the hessian
66: . Hpre - Matrix that will be used to construct the preconditioner, can be the same as `H`
67: . func - Hessian evaluation routine
68: - ctx - user-defined context for private data for the Hessian evaluation routine
70: Calling sequence of func:
71: $ func(Tao tao,Vec x,Mat H,Mat Hpre,void *ctx);
73: + tao - the Tao context
74: . x - input vector
75: . H - Hessian matrix
76: . Hpre - matrix used to construct the preconditioner, usually the same as `H`
77: - ctx - [optional] user-defined Hessian context
79: Level: beginner
81: .seealso: [](chapter_tao), `Tao`, TaoType`, `TaoGetObjective()`, `TaoGetGradient()`, `TaoGetObjectiveAndGradient()`, `TaoSetHessian()`
82: @*/
83: PetscErrorCode TaoGetHessian(Tao tao, Mat *H, Mat *Hpre, PetscErrorCode (**func)(Tao, Vec, Mat, Mat, void *), void **ctx)
84: {
85: PetscFunctionBegin;
87: if (H) *H = tao->hessian;
88: if (Hpre) *Hpre = tao->hessian_pre;
89: if (ctx) *ctx = tao->user_hessP;
90: if (func) *func = tao->ops->computehessian;
91: PetscFunctionReturn(PETSC_SUCCESS);
92: }
94: PetscErrorCode TaoTestHessian(Tao tao)
95: {
96: Mat A, B, C, D, hessian;
97: Vec x = tao->solution;
98: PetscReal nrm, gnorm;
99: PetscReal threshold = 1.e-5;
100: PetscInt m, n, M, N;
101: PetscBool complete_print = PETSC_FALSE, test = PETSC_FALSE, flg;
102: PetscViewer viewer, mviewer;
103: MPI_Comm comm;
104: PetscInt tabs;
105: static PetscBool directionsprinted = PETSC_FALSE;
106: PetscViewerFormat format;
108: PetscFunctionBegin;
109: PetscObjectOptionsBegin((PetscObject)tao);
110: PetscCall(PetscOptionsName("-tao_test_hessian", "Compare hand-coded and finite difference Hessians", "None", &test));
111: PetscCall(PetscOptionsReal("-tao_test_hessian", "Threshold for element difference between hand-coded and finite difference being meaningful", "None", threshold, &threshold, NULL));
112: PetscCall(PetscOptionsViewer("-tao_test_hessian_view", "View difference between hand-coded and finite difference Hessians element entries", "None", &mviewer, &format, &complete_print));
113: PetscOptionsEnd();
114: if (!test) PetscFunctionReturn(PETSC_SUCCESS);
116: PetscCall(PetscObjectGetComm((PetscObject)tao, &comm));
117: PetscCall(PetscViewerASCIIGetStdout(comm, &viewer));
118: PetscCall(PetscViewerASCIIGetTab(viewer, &tabs));
119: PetscCall(PetscViewerASCIISetTab(viewer, ((PetscObject)tao)->tablevel));
120: PetscCall(PetscViewerASCIIPrintf(viewer, " ---------- Testing Hessian -------------\n"));
121: if (!complete_print && !directionsprinted) {
122: PetscCall(PetscViewerASCIIPrintf(viewer, " Run with -tao_test_hessian_view and optionally -tao_test_hessian <threshold> to show difference\n"));
123: PetscCall(PetscViewerASCIIPrintf(viewer, " of hand-coded and finite difference Hessian entries greater than <threshold>.\n"));
124: }
125: if (!directionsprinted) {
126: PetscCall(PetscViewerASCIIPrintf(viewer, " Testing hand-coded Hessian, if (for double precision runs) ||J - Jfd||_F/||J||_F is\n"));
127: PetscCall(PetscViewerASCIIPrintf(viewer, " O(1.e-8), the hand-coded Hessian is probably correct.\n"));
128: directionsprinted = PETSC_TRUE;
129: }
130: if (complete_print) PetscCall(PetscViewerPushFormat(mviewer, format));
132: PetscCall(PetscObjectTypeCompare((PetscObject)tao->hessian, MATMFFD, &flg));
133: if (!flg) hessian = tao->hessian;
134: else hessian = tao->hessian_pre;
136: while (hessian) {
137: PetscCall(PetscObjectBaseTypeCompareAny((PetscObject)hessian, &flg, MATSEQAIJ, MATMPIAIJ, MATSEQDENSE, MATMPIDENSE, MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPIBAIJ, ""));
138: if (flg) {
139: A = hessian;
140: PetscCall(PetscObjectReference((PetscObject)A));
141: } else {
142: PetscCall(MatComputeOperator(hessian, MATAIJ, &A));
143: }
145: PetscCall(MatCreate(PetscObjectComm((PetscObject)A), &B));
146: PetscCall(MatGetSize(A, &M, &N));
147: PetscCall(MatGetLocalSize(A, &m, &n));
148: PetscCall(MatSetSizes(B, m, n, M, N));
149: PetscCall(MatSetType(B, ((PetscObject)A)->type_name));
150: PetscCall(MatSetUp(B));
151: PetscCall(MatSetOption(B, MAT_NEW_NONZERO_ALLOCATION_ERR, PETSC_FALSE));
153: PetscCall(TaoDefaultComputeHessian(tao, x, B, B, NULL));
155: PetscCall(MatDuplicate(B, MAT_COPY_VALUES, &D));
156: PetscCall(MatAYPX(D, -1.0, A, DIFFERENT_NONZERO_PATTERN));
157: PetscCall(MatNorm(D, NORM_FROBENIUS, &nrm));
158: PetscCall(MatNorm(A, NORM_FROBENIUS, &gnorm));
159: PetscCall(MatDestroy(&D));
160: if (!gnorm) gnorm = 1; /* just in case */
161: PetscCall(PetscViewerASCIIPrintf(viewer, " ||H - Hfd||_F/||H||_F = %g, ||H - Hfd||_F = %g\n", (double)(nrm / gnorm), (double)nrm));
163: if (complete_print) {
164: PetscCall(PetscViewerASCIIPrintf(viewer, " Hand-coded Hessian ----------\n"));
165: PetscCall(MatView(A, mviewer));
166: PetscCall(PetscViewerASCIIPrintf(viewer, " Finite difference Hessian ----------\n"));
167: PetscCall(MatView(B, mviewer));
168: }
170: if (complete_print) {
171: PetscInt Istart, Iend, *ccols, bncols, cncols, j, row;
172: PetscScalar *cvals;
173: const PetscInt *bcols;
174: const PetscScalar *bvals;
176: PetscCall(MatAYPX(B, -1.0, A, DIFFERENT_NONZERO_PATTERN));
177: PetscCall(MatCreate(PetscObjectComm((PetscObject)A), &C));
178: PetscCall(MatSetSizes(C, m, n, M, N));
179: PetscCall(MatSetType(C, ((PetscObject)A)->type_name));
180: PetscCall(MatSetUp(C));
181: PetscCall(MatSetOption(C, MAT_NEW_NONZERO_ALLOCATION_ERR, PETSC_FALSE));
182: PetscCall(MatGetOwnershipRange(B, &Istart, &Iend));
184: for (row = Istart; row < Iend; row++) {
185: PetscCall(MatGetRow(B, row, &bncols, &bcols, &bvals));
186: PetscCall(PetscMalloc2(bncols, &ccols, bncols, &cvals));
187: for (j = 0, cncols = 0; j < bncols; j++) {
188: if (PetscAbsScalar(bvals[j]) > threshold) {
189: ccols[cncols] = bcols[j];
190: cvals[cncols] = bvals[j];
191: cncols += 1;
192: }
193: }
194: if (cncols) PetscCall(MatSetValues(C, 1, &row, cncols, ccols, cvals, INSERT_VALUES));
195: PetscCall(MatRestoreRow(B, row, &bncols, &bcols, &bvals));
196: PetscCall(PetscFree2(ccols, cvals));
197: }
198: PetscCall(MatAssemblyBegin(C, MAT_FINAL_ASSEMBLY));
199: PetscCall(MatAssemblyEnd(C, MAT_FINAL_ASSEMBLY));
200: PetscCall(PetscViewerASCIIPrintf(viewer, " Finite-difference minus hand-coded Hessian with tolerance %g ----------\n", (double)threshold));
201: PetscCall(MatView(C, mviewer));
202: PetscCall(MatDestroy(&C));
203: }
204: PetscCall(MatDestroy(&A));
205: PetscCall(MatDestroy(&B));
207: if (hessian != tao->hessian_pre) {
208: hessian = tao->hessian_pre;
209: PetscCall(PetscViewerASCIIPrintf(viewer, " ---------- Testing Hessian for preconditioner -------------\n"));
210: } else hessian = NULL;
211: }
212: if (complete_print) {
213: PetscCall(PetscViewerPopFormat(mviewer));
214: PetscCall(PetscViewerDestroy(&mviewer));
215: }
216: PetscCall(PetscViewerASCIISetTab(viewer, tabs));
217: PetscFunctionReturn(PETSC_SUCCESS);
218: }
220: /*@C
221: TaoComputeHessian - Computes the Hessian matrix that has been
222: set with `TaoSetHessian()`.
224: Collective
226: Input Parameters:
227: + tao - the Tao solver context
228: - X - input vector
230: Output Parameters:
231: + H - Hessian matrix
232: - Hpre - Preconditioning matrix
234: Options Database Keys:
235: + -tao_test_hessian - compare the user provided Hessian with one compute via finite differences to check for errors
236: . -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
237: - -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
239: Level: developer
241: Notes:
242: Most users should not need to explicitly call this routine, as it
243: is used internally within the minimization solvers.
245: `TaoComputeHessian()` is typically used within optimization algorithms,
246: so most users would not generally call this routine
247: themselves.
249: Developer Note:
250: The Hessian test mechanism follows `SNESTestJacobian()`.
252: .seealso: [](chapter_tao), `Tao`, `TaoComputeObjective()`, `TaoComputeObjectiveAndGradient()`, `TaoSetHessian()`
253: @*/
254: PetscErrorCode TaoComputeHessian(Tao tao, Vec X, Mat H, Mat Hpre)
255: {
256: PetscFunctionBegin;
259: PetscCheckSameComm(tao, 1, X, 2);
260: PetscCheck(tao->ops->computehessian, PetscObjectComm((PetscObject)tao), PETSC_ERR_ARG_WRONGSTATE, "TaoSetHessian() not called");
262: ++tao->nhess;
263: PetscCall(VecLockReadPush(X));
264: PetscCall(PetscLogEventBegin(TAO_HessianEval, tao, X, H, Hpre));
265: PetscCallBack("Tao callback Hessian", (*tao->ops->computehessian)(tao, X, H, Hpre, tao->user_hessP));
266: PetscCall(PetscLogEventEnd(TAO_HessianEval, tao, X, H, Hpre));
267: PetscCall(VecLockReadPop(X));
269: PetscCall(TaoTestHessian(tao));
270: PetscFunctionReturn(PETSC_SUCCESS);
271: }
273: /*@C
274: TaoComputeJacobian - Computes the Jacobian matrix that has been
275: set with TaoSetJacobianRoutine().
277: Collective
279: Input Parameters:
280: + tao - the Tao solver context
281: - X - input vector
283: Output Parameters:
284: + J - Jacobian matrix
285: - Jpre - Preconditioning matrix
287: Level: developer
289: Notes:
290: Most users should not need to explicitly call this routine, as it
291: is used internally within the minimization solvers.
293: `TaoComputeJacobian()` is typically used within minimization
294: implementations, so most users would not generally call this routine
295: themselves.
297: .seealso: [](chapter_tao), `TaoComputeObjective()`, `TaoComputeObjectiveAndGradient()`, `TaoSetJacobianRoutine()`
298: @*/
299: PetscErrorCode TaoComputeJacobian(Tao tao, Vec X, Mat J, Mat Jpre)
300: {
301: PetscFunctionBegin;
304: PetscCheckSameComm(tao, 1, X, 2);
305: ++tao->njac;
306: PetscCall(VecLockReadPush(X));
307: PetscCall(PetscLogEventBegin(TAO_JacobianEval, tao, X, J, Jpre));
308: PetscCallBack("Tao callback Jacobian", (*tao->ops->computejacobian)(tao, X, J, Jpre, tao->user_jacP));
309: PetscCall(PetscLogEventEnd(TAO_JacobianEval, tao, X, J, Jpre));
310: PetscCall(VecLockReadPop(X));
311: PetscFunctionReturn(PETSC_SUCCESS);
312: }
314: /*@C
315: TaoComputeResidualJacobian - Computes the least-squares residual Jacobian matrix that has been
316: set with `TaoSetJacobianResidual()`.
318: Collective
320: Input Parameters:
321: + tao - the Tao solver context
322: - X - input vector
324: Output Parameters:
325: + J - Jacobian matrix
326: - Jpre - Preconditioning matrix
328: Level: developer
330: Notes:
331: Most users should not need to explicitly call this routine, as it
332: is used internally within the minimization solvers.
334: `TaoComputeResidualJacobian()` is typically used within least-squares
335: implementations, so most users would not generally call this routine
336: themselves.
338: .seealso: [](chapter_tao), `Tao`, `TaoComputeResidual()`, `TaoSetJacobianResidual()`
339: @*/
340: PetscErrorCode TaoComputeResidualJacobian(Tao tao, Vec X, Mat J, Mat Jpre)
341: {
342: PetscFunctionBegin;
345: PetscCheckSameComm(tao, 1, X, 2);
346: ++tao->njac;
347: PetscCall(VecLockReadPush(X));
348: PetscCall(PetscLogEventBegin(TAO_JacobianEval, tao, X, J, Jpre));
349: PetscCallBack("Tao callback least-squares residual Jacobian", (*tao->ops->computeresidualjacobian)(tao, X, J, Jpre, tao->user_lsjacP));
350: PetscCall(PetscLogEventEnd(TAO_JacobianEval, tao, X, J, Jpre));
351: PetscCall(VecLockReadPop(X));
352: PetscFunctionReturn(PETSC_SUCCESS);
353: }
355: /*@C
356: TaoComputeJacobianState - Computes the Jacobian matrix that has been
357: set with `TaoSetJacobianStateRoutine()`.
359: Collective
361: Input Parameters:
362: + tao - the `Tao` solver context
363: - X - input vector
365: Output Parameters:
366: + J - Jacobian matrix
367: . Jpre - matrix used to construct the preconditioner, often the same as `J`
368: - Jinv - unknown
370: Level: developer
372: Note:
373: Most users should not need to explicitly call this routine, as it
374: is used internally within the optimization algorithms.
376: .seealso: [](chapter_tao), `Tao`, `TaoComputeObjective()`, `TaoComputeObjectiveAndGradient()`, `TaoSetJacobianStateRoutine()`, `TaoComputeJacobianDesign()`, `TaoSetStateDesignIS()`
377: @*/
378: PetscErrorCode TaoComputeJacobianState(Tao tao, Vec X, Mat J, Mat Jpre, Mat Jinv)
379: {
380: PetscFunctionBegin;
383: PetscCheckSameComm(tao, 1, X, 2);
384: ++tao->njac_state;
385: PetscCall(VecLockReadPush(X));
386: PetscCall(PetscLogEventBegin(TAO_JacobianEval, tao, X, J, Jpre));
387: PetscCallBack("Tao callback Jacobian(state)", (*tao->ops->computejacobianstate)(tao, X, J, Jpre, Jinv, tao->user_jac_stateP));
388: PetscCall(PetscLogEventEnd(TAO_JacobianEval, tao, X, J, Jpre));
389: PetscCall(VecLockReadPop(X));
390: PetscFunctionReturn(PETSC_SUCCESS);
391: }
393: /*@C
394: TaoComputeJacobianDesign - Computes the Jacobian matrix that has been
395: set with `TaoSetJacobianDesignRoutine()`.
397: Collective
399: Input Parameters:
400: + tao - the Tao solver context
401: - X - input vector
403: Output Parameters:
404: . J - Jacobian matrix
406: Level: developer
408: Note:
409: Most users should not need to explicitly call this routine, as it
410: is used internally within the optimization algorithms.
412: .seealso: [](chapter_tao), `Tao`, `TaoComputeObjective()`, `TaoComputeObjectiveAndGradient()`, `TaoSetJacobianDesignRoutine()`, `TaoComputeJacobianDesign()`, `TaoSetStateDesignIS()`
413: @*/
414: PetscErrorCode TaoComputeJacobianDesign(Tao tao, Vec X, Mat J)
415: {
416: PetscFunctionBegin;
419: PetscCheckSameComm(tao, 1, X, 2);
420: ++tao->njac_design;
421: PetscCall(VecLockReadPush(X));
422: PetscCall(PetscLogEventBegin(TAO_JacobianEval, tao, X, J, NULL));
423: PetscCallBack("Tao callback Jacobian(design)", (*tao->ops->computejacobiandesign)(tao, X, J, tao->user_jac_designP));
424: PetscCall(PetscLogEventEnd(TAO_JacobianEval, tao, X, J, NULL));
425: PetscCall(VecLockReadPop(X));
426: PetscFunctionReturn(PETSC_SUCCESS);
427: }
429: /*@C
430: TaoSetJacobianRoutine - Sets the function to compute the Jacobian as well as the location to store the matrix.
432: Logically collective
434: Input Parameters:
435: + tao - the `Tao` context
436: . J - Matrix used for the Jacobian
437: . Jpre - Matrix that will be used to construct the preconditioner, can be same as `J`
438: . func - Jacobian evaluation routine
439: - ctx - [optional] user-defined context for private data for the
440: Jacobian evaluation routine (may be `NULL`)
442: Calling sequence of func:
443: $ func(Tao tao,Vec x,Mat J,Mat Jpre,void *ctx);
445: + tao - the `Tao` context
446: . x - input vector
447: . J - Jacobian matrix
448: . Jpre - matrix used to construct the preconditioner, usually the same as `J`
449: - ctx - [optional] user-defined Jacobian context
451: Level: intermediate
453: .seealso: [](chapter_tao), `Tao`, `TaoSetGradient()`, `TaoSetObjective()`
454: @*/
455: PetscErrorCode TaoSetJacobianRoutine(Tao tao, Mat J, Mat Jpre, PetscErrorCode (*func)(Tao, Vec, Mat, Mat, void *), void *ctx)
456: {
457: PetscFunctionBegin;
459: if (J) {
461: PetscCheckSameComm(tao, 1, J, 2);
462: }
463: if (Jpre) {
465: PetscCheckSameComm(tao, 1, Jpre, 3);
466: }
467: if (ctx) tao->user_jacP = ctx;
468: if (func) tao->ops->computejacobian = func;
469: if (J) {
470: PetscCall(PetscObjectReference((PetscObject)J));
471: PetscCall(MatDestroy(&tao->jacobian));
472: tao->jacobian = J;
473: }
474: if (Jpre) {
475: PetscCall(PetscObjectReference((PetscObject)Jpre));
476: PetscCall(MatDestroy(&tao->jacobian_pre));
477: tao->jacobian_pre = Jpre;
478: }
479: PetscFunctionReturn(PETSC_SUCCESS);
480: }
482: /*@C
483: TaoSetJacobianResidualRoutine - Sets the function to compute the least-squares residual Jacobian as well as the
484: location to store the matrix.
486: Logically collective
488: Input Parameters:
489: + tao - the `Tao` context
490: . J - Matrix used for the jacobian
491: . Jpre - Matrix that will be used to construct the preconditioner, can be same as `J`
492: . func - Jacobian evaluation routine
493: - ctx - [optional] user-defined context for private data for the
494: Jacobian evaluation routine (may be `NULL`)
496: Calling sequence of func:
497: $ func(Tao tao,Vec x,Mat J,Mat Jpre,void *ctx);
499: + tao - the `Tao` context
500: . x - input vector
501: . J - Jacobian matrix
502: . Jpre - matrix used to construct the preconditioner, usually the same as `J`
503: - ctx - [optional] user-defined Jacobian context
505: Level: intermediate
507: .seealso: [](chapter_tao), `Tao`, `TaoSetGradient()`, `TaoSetObjective()`
508: @*/
509: PetscErrorCode TaoSetJacobianResidualRoutine(Tao tao, Mat J, Mat Jpre, PetscErrorCode (*func)(Tao, Vec, Mat, Mat, void *), void *ctx)
510: {
511: PetscFunctionBegin;
513: if (J) {
515: PetscCheckSameComm(tao, 1, J, 2);
516: }
517: if (Jpre) {
519: PetscCheckSameComm(tao, 1, Jpre, 3);
520: }
521: if (ctx) tao->user_lsjacP = ctx;
522: if (func) tao->ops->computeresidualjacobian = func;
523: if (J) {
524: PetscCall(PetscObjectReference((PetscObject)J));
525: PetscCall(MatDestroy(&tao->ls_jac));
526: tao->ls_jac = J;
527: }
528: if (Jpre) {
529: PetscCall(PetscObjectReference((PetscObject)Jpre));
530: PetscCall(MatDestroy(&tao->ls_jac_pre));
531: tao->ls_jac_pre = Jpre;
532: }
533: PetscFunctionReturn(PETSC_SUCCESS);
534: }
536: /*@C
537: TaoSetJacobianStateRoutine - Sets the function to compute the Jacobian
538: (and its inverse) of the constraint function with respect to the state variables.
539: Used only for PDE-constrained optimization.
541: Logically collective
543: Input Parameters:
544: + tao - the `Tao` context
545: . J - Matrix used for the Jacobian
546: . Jpre - Matrix that will be used to construct the preconditioner, can be same as `J`. Only used if `Jinv` is `NULL`
547: . Jinv - [optional] Matrix used to apply the inverse of the state Jacobian. Use `NULL` to default to PETSc `KSP` solvers to apply the inverse.
548: . func - Jacobian evaluation routine
549: - ctx - [optional] user-defined context for private data for the
550: Jacobian evaluation routine (may be `NULL`)
552: Calling sequence of func:
553: $ func(Tao tao,Vec x,Mat J,Mat Jpre,Mat Jinv,void *ctx);
555: + tao - the `Tao` context
556: . x - input vector
557: . J - Jacobian matrix
558: . Jpre - matrix used to construct the preconditioner, usually the same as `J`
559: . Jinv - inverse of J
560: - ctx - [optional] user-defined Jacobian context
562: Level: intermediate
564: .seealso: [](chapter_tao), `Tao`, `TaoComputeJacobianState()`, `TaoSetJacobianDesignRoutine()`, `TaoSetStateDesignIS()`
565: @*/
566: PetscErrorCode TaoSetJacobianStateRoutine(Tao tao, Mat J, Mat Jpre, Mat Jinv, PetscErrorCode (*func)(Tao, Vec, Mat, Mat, Mat, void *), void *ctx)
567: {
568: PetscFunctionBegin;
570: if (J) {
572: PetscCheckSameComm(tao, 1, J, 2);
573: }
574: if (Jpre) {
576: PetscCheckSameComm(tao, 1, Jpre, 3);
577: }
578: if (Jinv) {
580: PetscCheckSameComm(tao, 1, Jinv, 4);
581: }
582: if (ctx) tao->user_jac_stateP = ctx;
583: if (func) tao->ops->computejacobianstate = func;
584: if (J) {
585: PetscCall(PetscObjectReference((PetscObject)J));
586: PetscCall(MatDestroy(&tao->jacobian_state));
587: tao->jacobian_state = J;
588: }
589: if (Jpre) {
590: PetscCall(PetscObjectReference((PetscObject)Jpre));
591: PetscCall(MatDestroy(&tao->jacobian_state_pre));
592: tao->jacobian_state_pre = Jpre;
593: }
594: if (Jinv) {
595: PetscCall(PetscObjectReference((PetscObject)Jinv));
596: PetscCall(MatDestroy(&tao->jacobian_state_inv));
597: tao->jacobian_state_inv = Jinv;
598: }
599: PetscFunctionReturn(PETSC_SUCCESS);
600: }
602: /*@C
603: TaoSetJacobianDesignRoutine - Sets the function to compute the Jacobian of
604: the constraint function with respect to the design variables. Used only for
605: PDE-constrained optimization.
607: Logically collective
609: Input Parameters:
610: + tao - the `Tao` context
611: . J - Matrix used for the Jacobian
612: . func - Jacobian evaluation routine
613: - ctx - [optional] user-defined context for private data for the
614: Jacobian evaluation routine (may be `NULL`)
616: Calling sequence of func:
617: $ func(Tao tao,Vec x,Mat J,void *ctx);
619: + tao - the `Tao` context
620: . x - input vector
621: . J - Jacobian matrix
622: - ctx - [optional] user-defined Jacobian context
624: Level: intermediate
626: .seealso: [](chapter_tao), `Tao`, `TaoComputeJacobianDesign()`, `TaoSetJacobianStateRoutine()`, `TaoSetStateDesignIS()`
627: @*/
628: PetscErrorCode TaoSetJacobianDesignRoutine(Tao tao, Mat J, PetscErrorCode (*func)(Tao, Vec, Mat, void *), void *ctx)
629: {
630: PetscFunctionBegin;
632: if (J) {
634: PetscCheckSameComm(tao, 1, J, 2);
635: }
636: if (ctx) tao->user_jac_designP = ctx;
637: if (func) tao->ops->computejacobiandesign = func;
638: if (J) {
639: PetscCall(PetscObjectReference((PetscObject)J));
640: PetscCall(MatDestroy(&tao->jacobian_design));
641: tao->jacobian_design = J;
642: }
643: PetscFunctionReturn(PETSC_SUCCESS);
644: }
646: /*@
647: TaoSetStateDesignIS - Indicate to the `Tao` object which variables in the
648: solution vector are state variables and which are design. Only applies to
649: PDE-constrained optimization.
651: Logically Collective
653: Input Parameters:
654: + tao - The `Tao` context
655: . s_is - the index set corresponding to the state variables
656: - d_is - the index set corresponding to the design variables
658: Level: intermediate
660: .seealso: [](chapter_tao), `Tao`, `TaoSetJacobianStateRoutine()`, `TaoSetJacobianDesignRoutine()`
661: @*/
662: PetscErrorCode TaoSetStateDesignIS(Tao tao, IS s_is, IS d_is)
663: {
664: PetscFunctionBegin;
665: PetscCall(PetscObjectReference((PetscObject)s_is));
666: PetscCall(ISDestroy(&tao->state_is));
667: tao->state_is = s_is;
668: PetscCall(PetscObjectReference((PetscObject)(d_is)));
669: PetscCall(ISDestroy(&tao->design_is));
670: tao->design_is = d_is;
671: PetscFunctionReturn(PETSC_SUCCESS);
672: }
674: /*@C
675: TaoComputeJacobianEquality - Computes the Jacobian matrix that has been
676: set with `TaoSetJacobianEqualityRoutine()`.
678: Collective
680: Input Parameters:
681: + tao - the `Tao` solver context
682: - X - input vector
684: Output Parameters:
685: + J - Jacobian matrix
686: - Jpre - matrix used to construct the preconditioner, often the same as `J`
688: Level: developer
690: Notes:
691: Most users should not need to explicitly call this routine, as it
692: is used internally within the optimization algorithms.
694: .seealso: [](chapter_tao), `TaoComputeObjective()`, `TaoComputeObjectiveAndGradient()`, `TaoSetJacobianStateRoutine()`, `TaoComputeJacobianDesign()`, `TaoSetStateDesignIS()`
695: @*/
696: PetscErrorCode TaoComputeJacobianEquality(Tao tao, Vec X, Mat J, Mat Jpre)
697: {
698: PetscFunctionBegin;
701: PetscCheckSameComm(tao, 1, X, 2);
702: ++tao->njac_equality;
703: PetscCall(VecLockReadPush(X));
704: PetscCall(PetscLogEventBegin(TAO_JacobianEval, tao, X, J, Jpre));
705: PetscCallBack("Tao callback Jacobian(equality)", (*tao->ops->computejacobianequality)(tao, X, J, Jpre, tao->user_jac_equalityP));
706: PetscCall(PetscLogEventEnd(TAO_JacobianEval, tao, X, J, Jpre));
707: PetscCall(VecLockReadPop(X));
708: PetscFunctionReturn(PETSC_SUCCESS);
709: }
711: /*@C
712: TaoComputeJacobianInequality - Computes the Jacobian matrix that has been
713: set with `TaoSetJacobianInequalityRoutine()`.
715: Collective
717: Input Parameters:
718: + tao - the `Tao` solver context
719: - X - input vector
721: Output Parameters:
722: + J - Jacobian matrix
723: - Jpre - matrix used to construct the preconditioner
725: Level: developer
727: Note:
728: Most users should not need to explicitly call this routine, as it
729: is used internally within the minimization solvers.
731: .seealso: [](chapter_tao), `Tao`, `TaoComputeObjective()`, `TaoComputeObjectiveAndGradient()`, `TaoSetJacobianStateRoutine()`, `TaoComputeJacobianDesign()`, `TaoSetStateDesignIS()`
732: @*/
733: PetscErrorCode TaoComputeJacobianInequality(Tao tao, Vec X, Mat J, Mat Jpre)
734: {
735: PetscFunctionBegin;
738: PetscCheckSameComm(tao, 1, X, 2);
739: ++tao->njac_inequality;
740: PetscCall(VecLockReadPush(X));
741: PetscCall(PetscLogEventBegin(TAO_JacobianEval, tao, X, J, Jpre));
742: PetscCallBack("Tao callback Jacobian (inequality)", (*tao->ops->computejacobianinequality)(tao, X, J, Jpre, tao->user_jac_inequalityP));
743: PetscCall(PetscLogEventEnd(TAO_JacobianEval, tao, X, J, Jpre));
744: PetscCall(VecLockReadPop(X));
745: PetscFunctionReturn(PETSC_SUCCESS);
746: }
748: /*@C
749: TaoSetJacobianEqualityRoutine - Sets the function to compute the Jacobian
750: (and its inverse) of the constraint function with respect to the equality variables.
751: Used only for PDE-constrained optimization.
753: Logically collective
755: Input Parameters:
756: + tao - the `Tao` context
757: . J - Matrix used for the Jacobian
758: . Jpre - Matrix that will be used to construct the preconditioner, can be same as `J`.
759: . func - Jacobian evaluation routine
760: - ctx - [optional] user-defined context for private data for the
761: Jacobian evaluation routine (may be `NULL`)
763: Calling sequence of func:
764: $ func(Tao tao,Vec x,Mat J,Mat Jpre,void *ctx);
766: + tao - the `Tao` context
767: . x - input vector
768: . J - Jacobian matrix
769: . Jpre - matrix used to construct the preconditioner, usually the same as `J`
770: - ctx - [optional] user-defined Jacobian context
772: Level: intermediate
774: .seealso: [](chapter_tao), `Tao`, `TaoComputeJacobianEquality()`, `TaoSetJacobianDesignRoutine()`, `TaoSetEqualityDesignIS()`
775: @*/
776: PetscErrorCode TaoSetJacobianEqualityRoutine(Tao tao, Mat J, Mat Jpre, PetscErrorCode (*func)(Tao, Vec, Mat, Mat, void *), void *ctx)
777: {
778: PetscFunctionBegin;
780: if (J) {
782: PetscCheckSameComm(tao, 1, J, 2);
783: }
784: if (Jpre) {
786: PetscCheckSameComm(tao, 1, Jpre, 3);
787: }
788: if (ctx) tao->user_jac_equalityP = ctx;
789: if (func) tao->ops->computejacobianequality = func;
790: if (J) {
791: PetscCall(PetscObjectReference((PetscObject)J));
792: PetscCall(MatDestroy(&tao->jacobian_equality));
793: tao->jacobian_equality = J;
794: }
795: if (Jpre) {
796: PetscCall(PetscObjectReference((PetscObject)Jpre));
797: PetscCall(MatDestroy(&tao->jacobian_equality_pre));
798: tao->jacobian_equality_pre = Jpre;
799: }
800: PetscFunctionReturn(PETSC_SUCCESS);
801: }
803: /*@C
804: TaoSetJacobianInequalityRoutine - Sets the function to compute the Jacobian
805: (and its inverse) of the constraint function with respect to the inequality variables.
806: Used only for PDE-constrained optimization.
808: Logically collective
810: Input Parameters:
811: + tao - the `Tao` context
812: . J - Matrix used for the Jacobian
813: . Jpre - Matrix that will be used to construct the preconditioner, can be same as `J`.
814: . func - Jacobian evaluation routine
815: - ctx - [optional] user-defined context for private data for the
816: Jacobian evaluation routine (may be `NULL`)
818: Calling sequence of func:
819: $ func(Tao tao,Vec x,Mat J,Mat Jpre,void *ctx);
821: + tao - the `Tao` context
822: . x - input vector
823: . J - Jacobian matrix
824: . Jpre - matrix used to construct the preconditioner, usually the same as `J`
825: - ctx - [optional] user-defined Jacobian context
827: Level: intermediate
829: .seealso: [](chapter_tao), `Tao`, `TaoComputeJacobianInequality()`, `TaoSetJacobianDesignRoutine()`, `TaoSetInequalityDesignIS()`
830: @*/
831: PetscErrorCode TaoSetJacobianInequalityRoutine(Tao tao, Mat J, Mat Jpre, PetscErrorCode (*func)(Tao, Vec, Mat, Mat, void *), void *ctx)
832: {
833: PetscFunctionBegin;
835: if (J) {
837: PetscCheckSameComm(tao, 1, J, 2);
838: }
839: if (Jpre) {
841: PetscCheckSameComm(tao, 1, Jpre, 3);
842: }
843: if (ctx) tao->user_jac_inequalityP = ctx;
844: if (func) tao->ops->computejacobianinequality = func;
845: if (J) {
846: PetscCall(PetscObjectReference((PetscObject)J));
847: PetscCall(MatDestroy(&tao->jacobian_inequality));
848: tao->jacobian_inequality = J;
849: }
850: if (Jpre) {
851: PetscCall(PetscObjectReference((PetscObject)Jpre));
852: PetscCall(MatDestroy(&tao->jacobian_inequality_pre));
853: tao->jacobian_inequality_pre = Jpre;
854: }
855: PetscFunctionReturn(PETSC_SUCCESS);
856: }