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: }