Date: 2022-03-04T17:39:48+00:00

Actual source code: taosolver_hj.c

      1: #include <petsc/private/taoimpl.h>

      3: /*@C
      4:    TaoSetHessianRoutine - 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
     26: @*/
     27: PetscErrorCode TaoSetHessianRoutine(Tao tao, Mat H, Mat Hpre, PetscErrorCode (*func)(Tao, Vec, Mat, Mat, void*), void *ctx)
     28: {

     33:   if (H) {
     36:   }
     37:   if (Hpre) {
     40:   }
     41:   if (ctx) {
     42:     tao->user_hessP = ctx;
     43:   }
     44:   if (func) {
     45:     tao->ops->computehessian = func;
     46:   }
     47:   if (H) {
     48:     PetscObjectReference((PetscObject)H);
     49:     MatDestroy(&tao->hessian);
     50:     tao->hessian = H;
     51:   }
     52:   if (Hpre) {
     53:     PetscObjectReference((PetscObject)Hpre);
     54:     MatDestroy(&tao->hessian_pre);
     55:     tao->hessian_pre = Hpre;
     56:   }
     57:   return(0);
     58: }

     60: PetscErrorCode TaoTestHessian(Tao tao)
     61: {
     62:   Mat               A,B,C,D,hessian;
     63:   Vec               x = tao->solution;
     64:   PetscErrorCode    ierr;
     65:   PetscReal         nrm,gnorm;
     66:   PetscReal         threshold = 1.e-5;
     67:   PetscInt          m,n,M,N;
     68:   PetscBool         complete_print = PETSC_FALSE,test = PETSC_FALSE,flg;
     69:   PetscViewer       viewer,mviewer;
     70:   MPI_Comm          comm;
     71:   PetscInt          tabs;
     72:   static PetscBool  directionsprinted = PETSC_FALSE;
     73:   PetscViewerFormat format;

     76:   PetscObjectOptionsBegin((PetscObject)tao);
     77:   PetscOptionsName("-tao_test_hessian","Compare hand-coded and finite difference Hessians","None",&test);
     78:   PetscOptionsReal("-tao_test_hessian", "Threshold for element difference between hand-coded and finite difference being meaningful","None",threshold,&threshold,NULL);
     79:   PetscOptionsViewer("-tao_test_hessian_view","View difference between hand-coded and finite difference Hessians element entries","None",&mviewer,&format,&complete_print);
     80:   PetscOptionsEnd();
     81:   if (!test) return(0);

     83:   PetscObjectGetComm((PetscObject)tao,&comm);
     84:   PetscViewerASCIIGetStdout(comm,&viewer);
     85:   PetscViewerASCIIGetTab(viewer, &tabs);
     86:   PetscViewerASCIISetTab(viewer, ((PetscObject)tao)->tablevel);
     87:   PetscViewerASCIIPrintf(viewer,"  ---------- Testing Hessian -------------\n");
     88:   if (!complete_print && !directionsprinted) {
     89:     PetscViewerASCIIPrintf(viewer,"  Run with -tao_test_hessian_view and optionally -tao_test_hessian <threshold> to show difference\n");
     90:     PetscViewerASCIIPrintf(viewer,"    of hand-coded and finite difference Hessian entries greater than <threshold>.\n");
     91:   }
     92:   if (!directionsprinted) {
     93:     PetscViewerASCIIPrintf(viewer,"  Testing hand-coded Hessian, if (for double precision runs) ||J - Jfd||_F/||J||_F is\n");
     94:     PetscViewerASCIIPrintf(viewer,"    O(1.e-8), the hand-coded Hessian is probably correct.\n");
     95:     directionsprinted = PETSC_TRUE;
     96:   }
     97:   if (complete_print) {
     98:     PetscViewerPushFormat(mviewer,format);
     99:   }

    101:   PetscObjectTypeCompare((PetscObject)tao->hessian,MATMFFD,&flg);
    102:   if (!flg) hessian = tao->hessian;
    103:   else hessian = tao->hessian_pre;

    105:   while (hessian) {
    106:     PetscObjectBaseTypeCompareAny((PetscObject)hessian,&flg,MATSEQAIJ,MATMPIAIJ,MATSEQDENSE,MATMPIDENSE,MATSEQBAIJ,MATMPIBAIJ,MATSEQSBAIJ,MATMPIBAIJ,"");
    107:     if (flg) {
    108:       A    = hessian;
    109:       PetscObjectReference((PetscObject)A);
    110:     } else {
    111:       MatComputeOperator(hessian,MATAIJ,&A);
    112:     }

    114:     MatCreate(PetscObjectComm((PetscObject)A),&B);
    115:     MatGetSize(A,&M,&N);
    116:     MatGetLocalSize(A,&m,&n);
    117:     MatSetSizes(B,m,n,M,N);
    118:     MatSetType(B,((PetscObject)A)->type_name);
    119:     MatSetUp(B);
    120:     MatSetOption(B,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_FALSE);

    122:     TaoDefaultComputeHessian(tao,x,B,B,NULL);

    124:     MatDuplicate(B,MAT_COPY_VALUES,&D);
    125:     MatAYPX(D,-1.0,A,DIFFERENT_NONZERO_PATTERN);
    126:     MatNorm(D,NORM_FROBENIUS,&nrm);
    127:     MatNorm(A,NORM_FROBENIUS,&gnorm);
    128:     MatDestroy(&D);
    129:     if (!gnorm) gnorm = 1; /* just in case */
    130:     PetscViewerASCIIPrintf(viewer,"  ||H - Hfd||_F/||H||_F = %g, ||H - Hfd||_F = %g\n",(double)(nrm/gnorm),(double)nrm);

    132:     if (complete_print) {
    133:       PetscViewerASCIIPrintf(viewer,"  Hand-coded Hessian ----------\n");
    134:       MatView(A,mviewer);
    135:       PetscViewerASCIIPrintf(viewer,"  Finite difference Hessian ----------\n");
    136:       MatView(B,mviewer);
    137:     }

    139:     if (complete_print) {
    140:       PetscInt          Istart, Iend, *ccols, bncols, cncols, j, row;
    141:       PetscScalar       *cvals;
    142:       const PetscInt    *bcols;
    143:       const PetscScalar *bvals;

    145:       MatAYPX(B,-1.0,A,DIFFERENT_NONZERO_PATTERN);
    146:       MatCreate(PetscObjectComm((PetscObject)A),&C);
    147:       MatSetSizes(C,m,n,M,N);
    148:       MatSetType(C,((PetscObject)A)->type_name);
    149:       MatSetUp(C);
    150:       MatSetOption(C,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_FALSE);
    151:       MatGetOwnershipRange(B,&Istart,&Iend);

    153:       for (row = Istart; row < Iend; row++) {
    154:         MatGetRow(B,row,&bncols,&bcols,&bvals);
    155:         PetscMalloc2(bncols,&ccols,bncols,&cvals);
    156:         for (j = 0, cncols = 0; j < bncols; j++) {
    157:           if (PetscAbsScalar(bvals[j]) > threshold) {
    158:             ccols[cncols] = bcols[j];
    159:             cvals[cncols] = bvals[j];
    160:             cncols += 1;
    161:           }
    162:         }
    163:         if (cncols) {
    164:           MatSetValues(C,1,&row,cncols,ccols,cvals,INSERT_VALUES);
    165:         }
    166:         MatRestoreRow(B,row,&bncols,&bcols,&bvals);
    167:         PetscFree2(ccols,cvals);
    168:       }
    169:       MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);
    170:       MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);
    171:       PetscViewerASCIIPrintf(viewer,"  Finite-difference minus hand-coded Hessian with tolerance %g ----------\n",(double)threshold);
    172:       MatView(C,mviewer);
    173:       MatDestroy(&C);
    174:     }
    175:     MatDestroy(&A);
    176:     MatDestroy(&B);

    178:     if (hessian != tao->hessian_pre) {
    179:       hessian = tao->hessian_pre;
    180:       PetscViewerASCIIPrintf(viewer,"  ---------- Testing Hessian for preconditioner -------------\n");
    181:     } else hessian = NULL;
    182:   }
    183:   if (complete_print) {
    184:     PetscViewerPopFormat(mviewer);
    185:     PetscViewerDestroy(&mviewer);
    186:   }
    187:   PetscViewerASCIISetTab(viewer,tabs);
    188:   return(0);
    189: }

    191: /*@C
    192:    TaoComputeHessian - Computes the Hessian matrix that has been
    193:    set with TaoSetHessianRoutine().

    195:    Collective on Tao

    197:    Input Parameters:
    198: +  tao - the Tao solver context
    199: -  X   - input vector

    201:    Output Parameters:
    202: +  H    - Hessian matrix
    203: -  Hpre - Preconditioning matrix

    205:    Options Database Keys:
    206: +     -tao_test_hessian - compare the user provided Hessian with one compute via finite differences to check for errors
    207: .     -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
    208: -     -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

    210:    Notes:
    211:    Most users should not need to explicitly call this routine, as it
    212:    is used internally within the minimization solvers.

    214:    TaoComputeHessian() is typically used within minimization
    215:    implementations, so most users would not generally call this routine
    216:    themselves.

    218:    Developer Notes:
    219:    The Hessian test mechanism follows SNESTestJacobian().

    221:    Level: developer

    223: .seealso: TaoComputeObjective(), TaoComputeObjectiveAndGradient(), TaoSetHessianRoutine()
    224: @*/
    225: PetscErrorCode TaoComputeHessian(Tao tao, Vec X, Mat H, Mat Hpre)
    226: {

    233:   if (!tao->ops->computehessian) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Must call TaoSetHessianRoutine() first");
    234:   ++tao->nhess;
    235:   VecLockReadPush(X);
    236:   PetscLogEventBegin(TAO_HessianEval,tao,X,H,Hpre);
    237:   PetscStackPush("Tao user Hessian function");
    238:   (*tao->ops->computehessian)(tao,X,H,Hpre,tao->user_hessP);
    239:   PetscStackPop;
    240:   PetscLogEventEnd(TAO_HessianEval,tao,X,H,Hpre);
    241:   VecLockReadPop(X);

    243:   TaoTestHessian(tao);
    244:   return(0);
    245: }

    247: /*@C
    248:    TaoComputeJacobian - Computes the Jacobian matrix that has been
    249:    set with TaoSetJacobianRoutine().

    251:    Collective on Tao

    253:    Input Parameters:
    254: +  tao - the Tao solver context
    255: -  X   - input vector

    257:    Output Parameters:
    258: +  J    - Jacobian matrix
    259: -  Jpre - Preconditioning matrix

    261:    Notes:
    262:    Most users should not need to explicitly call this routine, as it
    263:    is used internally within the minimization solvers.

    265:    TaoComputeJacobian() is typically used within minimization
    266:    implementations, so most users would not generally call this routine
    267:    themselves.

    269:    Level: developer

    271: .seealso: TaoComputeObjective(), TaoComputeObjectiveAndGradient(), TaoSetJacobianRoutine()
    272: @*/
    273: PetscErrorCode TaoComputeJacobian(Tao tao, Vec X, Mat J, Mat Jpre)
    274: {

    281:   if (!tao->ops->computejacobian) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Must call TaoSetJacobian() first");
    282:   ++tao->njac;
    283:   VecLockReadPush(X);
    284:   PetscLogEventBegin(TAO_JacobianEval,tao,X,J,Jpre);
    285:   PetscStackPush("Tao user Jacobian function");
    286:   (*tao->ops->computejacobian)(tao,X,J,Jpre,tao->user_jacP);
    287:   PetscStackPop;
    288:   PetscLogEventEnd(TAO_JacobianEval,tao,X,J,Jpre);
    289:   VecLockReadPop(X);
    290:   return(0);
    291: }

    293: /*@C
    294:    TaoComputeResidualJacobian - Computes the least-squares residual Jacobian matrix that has been
    295:    set with TaoSetJacobianResidual().

    297:    Collective on Tao

    299:    Input Parameters:
    300: +  tao - the Tao solver context
    301: -  X   - input vector

    303:    Output Parameters:
    304: +  J    - Jacobian matrix
    305: -  Jpre - Preconditioning matrix

    307:    Notes:
    308:    Most users should not need to explicitly call this routine, as it
    309:    is used internally within the minimization solvers.

    311:    TaoComputeResidualJacobian() is typically used within least-squares
    312:    implementations, so most users would not generally call this routine
    313:    themselves.

    315:    Level: developer

    317: .seealso: TaoComputeResidual(), TaoSetJacobianResidual()
    318: @*/
    319: PetscErrorCode TaoComputeResidualJacobian(Tao tao, Vec X, Mat J, Mat Jpre)
    320: {

    327:   if (!tao->ops->computeresidualjacobian) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Must call TaoSetResidualJacobian() first");
    328:   ++tao->njac;
    329:   VecLockReadPush(X);
    330:   PetscLogEventBegin(TAO_JacobianEval,tao,X,J,Jpre);
    331:   PetscStackPush("Tao user least-squares residual Jacobian function");
    332:   (*tao->ops->computeresidualjacobian)(tao,X,J,Jpre,tao->user_lsjacP);
    333:   PetscStackPop;
    334:   PetscLogEventEnd(TAO_JacobianEval,tao,X,J,Jpre);
    335:   VecLockReadPop(X);
    336:   return(0);
    337: }

    339: /*@C
    340:    TaoComputeJacobianState - Computes the Jacobian matrix that has been
    341:    set with TaoSetJacobianStateRoutine().

    343:    Collective on Tao

    345:    Input Parameters:
    346: +  tao - the Tao solver context
    347: -  X   - input vector

    349:    Output Parameters:
    350: +  J    - Jacobian matrix
    351: .  Jpre - Preconditioning matrix
    352: -  Jinv -

    354:    Notes:
    355:    Most users should not need to explicitly call this routine, as it
    356:    is used internally within the minimization solvers.

    358:    TaoComputeJacobianState() is typically used within minimization
    359:    implementations, so most users would not generally call this routine
    360:    themselves.

    362:    Level: developer

    364: .seealso: TaoComputeObjective(), TaoComputeObjectiveAndGradient(), TaoSetJacobianStateRoutine(), TaoComputeJacobianDesign(), TaoSetStateDesignIS()
    365: @*/
    366: PetscErrorCode TaoComputeJacobianState(Tao tao, Vec X, Mat J, Mat Jpre, Mat Jinv)
    367: {

    374:   if (!tao->ops->computejacobianstate) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Must call TaoSetJacobianState() first");
    375:   ++tao->njac_state;
    376:   VecLockReadPush(X);
    377:   PetscLogEventBegin(TAO_JacobianEval,tao,X,J,Jpre);
    378:   PetscStackPush("Tao user Jacobian(state) function");
    379:   (*tao->ops->computejacobianstate)(tao,X,J,Jpre,Jinv,tao->user_jac_stateP);
    380:   PetscStackPop;
    381:   PetscLogEventEnd(TAO_JacobianEval,tao,X,J,Jpre);
    382:   VecLockReadPop(X);
    383:   return(0);
    384: }

    386: /*@C
    387:    TaoComputeJacobianDesign - Computes the Jacobian matrix that has been
    388:    set with TaoSetJacobianDesignRoutine().

    390:    Collective on Tao

    392:    Input Parameters:
    393: +  tao - the Tao solver context
    394: -  X   - input vector

    396:    Output Parameters:
    397: .  J - Jacobian matrix

    399:    Notes:
    400:    Most users should not need to explicitly call this routine, as it
    401:    is used internally within the minimization solvers.

    403:    TaoComputeJacobianDesign() is typically used within minimization
    404:    implementations, so most users would not generally call this routine
    405:    themselves.

    407:    Level: developer

    409: .seealso:  TaoComputeObjective(), TaoComputeObjectiveAndGradient(), TaoSetJacobianDesignRoutine(), TaoComputeJacobianDesign(), TaoSetStateDesignIS()
    410: @*/
    411: PetscErrorCode TaoComputeJacobianDesign(Tao tao, Vec X, Mat J)
    412: {

    419:   if (!tao->ops->computejacobiandesign) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Must call TaoSetJacobianDesign() first");
    420:   ++tao->njac_design;
    421:   VecLockReadPush(X);
    422:   PetscLogEventBegin(TAO_JacobianEval,tao,X,J,NULL);
    423:   PetscStackPush("Tao user Jacobian(design) function");
    424:   (*tao->ops->computejacobiandesign)(tao,X,J,tao->user_jac_designP);
    425:   PetscStackPop;
    426:   PetscLogEventEnd(TAO_JacobianEval,tao,X,J,NULL);
    427:   VecLockReadPop(X);
    428:   return(0);
    429: }

    431: /*@C
    432:    TaoSetJacobianRoutine - Sets the function to compute the Jacobian as well as the location to store the matrix.

    434:    Logically collective on Tao

    436:    Input Parameters:
    437: +  tao  - the Tao context
    438: .  J    - Matrix used for the jacobian
    439: .  Jpre - Matrix that will be used operated on by preconditioner, can be same as J
    440: .  func - Jacobian evaluation routine
    441: -  ctx  - [optional] user-defined context for private data for the
    442:           Jacobian evaluation routine (may be NULL)

    444:    Calling sequence of func:
    445: $    func(Tao tao,Vec x,Mat J,Mat Jpre,void *ctx);

    447: +  tao  - the Tao  context
    448: .  x    - input vector
    449: .  J    - Jacobian matrix
    450: .  Jpre - preconditioning matrix, usually the same as J
    451: -  ctx  - [optional] user-defined Jacobian context

    453:    Level: intermediate
    454: @*/
    455: PetscErrorCode TaoSetJacobianRoutine(Tao tao, Mat J, Mat Jpre, PetscErrorCode (*func)(Tao, Vec, Mat, Mat, void*), void *ctx)
    456: {

    461:   if (J) {
    464:   }
    465:   if (Jpre) {
    468:   }
    469:   if (ctx) {
    470:     tao->user_jacP = ctx;
    471:   }
    472:   if (func) {
    473:     tao->ops->computejacobian = func;
    474:   }
    475:   if (J) {
    476:     PetscObjectReference((PetscObject)J);
    477:     MatDestroy(&tao->jacobian);
    478:     tao->jacobian = J;
    479:   }
    480:   if (Jpre) {
    481:     PetscObjectReference((PetscObject)Jpre);
    482:     MatDestroy(&tao->jacobian_pre);
    483:     tao->jacobian_pre=Jpre;
    484:   }
    485:   return(0);
    486: }

    488: /*@C
    489:    TaoSetJacobianResidualRoutine - Sets the function to compute the least-squares residual Jacobian as well as the
    490:    location to store the matrix.

    492:    Logically collective on Tao

    494:    Input Parameters:
    495: +  tao  - the Tao context
    496: .  J    - Matrix used for the jacobian
    497: .  Jpre - Matrix that will be used operated on by preconditioner, can be same as J
    498: .  func - Jacobian evaluation routine
    499: -  ctx  - [optional] user-defined context for private data for the
    500:           Jacobian evaluation routine (may be NULL)

    502:    Calling sequence of func:
    503: $    func(Tao tao,Vec x,Mat J,Mat Jpre,void *ctx);

    505: +  tao  - the Tao  context
    506: .  x    - input vector
    507: .  J    - Jacobian matrix
    508: .  Jpre - preconditioning matrix, usually the same as J
    509: -  ctx  - [optional] user-defined Jacobian context

    511:    Level: intermediate
    512: @*/
    513: PetscErrorCode TaoSetJacobianResidualRoutine(Tao tao, Mat J, Mat Jpre, PetscErrorCode (*func)(Tao, Vec, Mat, Mat, void*), void *ctx)
    514: {

    519:   if (J) {
    522:   }
    523:   if (Jpre) {
    526:   }
    527:   if (ctx) {
    528:     tao->user_lsjacP = ctx;
    529:   }
    530:   if (func) {
    531:     tao->ops->computeresidualjacobian = func;
    532:   }
    533:   if (J) {
    534:     PetscObjectReference((PetscObject)J);
    535:     MatDestroy(&tao->ls_jac);
    536:     tao->ls_jac = J;
    537:   }
    538:   if (Jpre) {
    539:     PetscObjectReference((PetscObject)Jpre);
    540:     MatDestroy(&tao->ls_jac_pre);
    541:     tao->ls_jac_pre=Jpre;
    542:   }
    543:   return(0);
    544: }

    546: /*@C
    547:    TaoSetJacobianStateRoutine - Sets the function to compute the Jacobian
    548:    (and its inverse) of the constraint function with respect to the state variables.
    549:    Used only for pde-constrained optimization.

    551:    Logically collective on Tao

    553:    Input Parameters:
    554: +  tao  - the Tao context
    555: .  J    - Matrix used for the jacobian
    556: .  Jpre - Matrix that will be used operated on by PETSc preconditioner, can be same as J.  Only used if Jinv is NULL
    557: .  Jinv - [optional] Matrix used to apply the inverse of the state jacobian. Use NULL to default to PETSc KSP solvers to apply the inverse.
    558: .  func - Jacobian evaluation routine
    559: -  ctx  - [optional] user-defined context for private data for the
    560:           Jacobian evaluation routine (may be NULL)

    562:    Calling sequence of func:
    563: $    func(Tao tao,Vec x,Mat J,Mat Jpre,Mat Jinv,void *ctx);

    565: +  tao  - the Tao  context
    566: .  x    - input vector
    567: .  J    - Jacobian matrix
    568: .  Jpre - preconditioner matrix, usually the same as J
    569: .  Jinv - inverse of J
    570: -  ctx  - [optional] user-defined Jacobian context

    572:    Level: intermediate
    573: .seealso: TaoComputeJacobianState(), TaoSetJacobianDesignRoutine(), TaoSetStateDesignIS()
    574: @*/
    575: PetscErrorCode TaoSetJacobianStateRoutine(Tao tao, Mat J, Mat Jpre, Mat Jinv, PetscErrorCode (*func)(Tao, Vec, Mat, Mat, Mat, void*), void *ctx)
    576: {

    581:   if (J) {
    584:   }
    585:   if (Jpre) {
    588:   }
    589:   if (Jinv) {
    592:   }
    593:   if (ctx) {
    594:     tao->user_jac_stateP = ctx;
    595:   }
    596:   if (func) {
    597:     tao->ops->computejacobianstate = func;
    598:   }
    599:   if (J) {
    600:     PetscObjectReference((PetscObject)J);
    601:     MatDestroy(&tao->jacobian_state);
    602:     tao->jacobian_state = J;
    603:   }
    604:   if (Jpre) {
    605:     PetscObjectReference((PetscObject)Jpre);
    606:     MatDestroy(&tao->jacobian_state_pre);
    607:     tao->jacobian_state_pre=Jpre;
    608:   }
    609:   if (Jinv) {
    610:     PetscObjectReference((PetscObject)Jinv);
    611:     MatDestroy(&tao->jacobian_state_inv);
    612:     tao->jacobian_state_inv=Jinv;
    613:   }
    614:   return(0);
    615: }

    617: /*@C
    618:    TaoSetJacobianDesignRoutine - Sets the function to compute the Jacobian of
    619:    the constraint function with respect to the design variables.  Used only for
    620:    pde-constrained optimization.

    622:    Logically collective on Tao

    624:    Input Parameters:
    625: +  tao  - the Tao context
    626: .  J    - Matrix used for the jacobian
    627: .  func - Jacobian evaluation routine
    628: -  ctx  - [optional] user-defined context for private data for the
    629:           Jacobian evaluation routine (may be NULL)

    631:    Calling sequence of func:
    632: $    func(Tao tao,Vec x,Mat J,void *ctx);

    634: +  tao - the Tao  context
    635: .  x   - input vector
    636: .  J   - Jacobian matrix
    637: -  ctx - [optional] user-defined Jacobian context

    639:    Level: intermediate

    641: .seealso: TaoComputeJacobianDesign(), TaoSetJacobianStateRoutine(), TaoSetStateDesignIS()
    642: @*/
    643: PetscErrorCode TaoSetJacobianDesignRoutine(Tao tao, Mat J, PetscErrorCode (*func)(Tao, Vec, Mat, void*), void *ctx)
    644: {

    649:   if (J) {
    652:   }
    653:   if (ctx) {
    654:     tao->user_jac_designP = ctx;
    655:   }
    656:   if (func) {
    657:     tao->ops->computejacobiandesign = func;
    658:   }
    659:   if (J) {
    660:     PetscObjectReference((PetscObject)J);
    661:     MatDestroy(&tao->jacobian_design);
    662:     tao->jacobian_design = J;
    663:   }
    664:   return(0);
    665: }

    667: /*@
    668:    TaoSetStateDesignIS - Indicate to the Tao which variables in the
    669:    solution vector are state variables and which are design.  Only applies to
    670:    pde-constrained optimization.

    672:    Logically Collective on Tao

    674:    Input Parameters:
    675: +  tao  - The Tao context
    676: .  s_is - the index set corresponding to the state variables
    677: -  d_is - the index set corresponding to the design variables

    679:    Level: intermediate

    681: .seealso: TaoSetJacobianStateRoutine(), TaoSetJacobianDesignRoutine()
    682: @*/
    683: PetscErrorCode TaoSetStateDesignIS(Tao tao, IS s_is, IS d_is)
    684: {

    688:   PetscObjectReference((PetscObject)s_is);
    689:   ISDestroy(&tao->state_is);
    690:   tao->state_is = s_is;
    691:   PetscObjectReference((PetscObject)(d_is));
    692:   ISDestroy(&tao->design_is);
    693:   tao->design_is = d_is;
    694:   return(0);
    695: }

    697: /*@C
    698:    TaoComputeJacobianEquality - Computes the Jacobian matrix that has been
    699:    set with TaoSetJacobianEqualityRoutine().

    701:    Collective on Tao

    703:    Input Parameters:
    704: +  tao - the Tao solver context
    705: -  X   - input vector

    707:    Output Parameters:
    708: +  J    - Jacobian matrix
    709: -  Jpre - Preconditioning matrix

    711:    Notes:
    712:    Most users should not need to explicitly call this routine, as it
    713:    is used internally within the minimization solvers.

    715:    Level: developer

    717: .seealso:  TaoComputeObjective(), TaoComputeObjectiveAndGradient(), TaoSetJacobianStateRoutine(), TaoComputeJacobianDesign(), TaoSetStateDesignIS()
    718: @*/
    719: PetscErrorCode TaoComputeJacobianEquality(Tao tao, Vec X, Mat J, Mat Jpre)
    720: {

    727:   if (!tao->ops->computejacobianequality) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Must call TaoSetJacobianEquality() first");
    728:   ++tao->njac_equality;
    729:   VecLockReadPush(X);
    730:   PetscLogEventBegin(TAO_JacobianEval,tao,X,J,Jpre);
    731:   PetscStackPush("Tao user Jacobian(equality) function");
    732:   (*tao->ops->computejacobianequality)(tao,X,J,Jpre,tao->user_jac_equalityP);
    733:   PetscStackPop;
    734:   PetscLogEventEnd(TAO_JacobianEval,tao,X,J,Jpre);
    735:   VecLockReadPop(X);
    736:   return(0);
    737: }

    739: /*@C
    740:    TaoComputeJacobianInequality - Computes the Jacobian matrix that has been
    741:    set with TaoSetJacobianInequalityRoutine().

    743:    Collective on Tao

    745:    Input Parameters:
    746: +  tao - the Tao solver context
    747: -  X   - input vector

    749:    Output Parameters:
    750: +  J    - Jacobian matrix
    751: -  Jpre - Preconditioning matrix

    753:    Notes:
    754:    Most users should not need to explicitly call this routine, as it
    755:    is used internally within the minimization solvers.

    757:    Level: developer

    759: .seealso:  TaoComputeObjective(), TaoComputeObjectiveAndGradient(), TaoSetJacobianStateRoutine(), TaoComputeJacobianDesign(), TaoSetStateDesignIS()
    760: @*/
    761: PetscErrorCode TaoComputeJacobianInequality(Tao tao, Vec X, Mat J, Mat Jpre)
    762: {

    769:   if (!tao->ops->computejacobianinequality) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Must call TaoSetJacobianInequality() first");
    770:   ++tao->njac_inequality;
    771:   VecLockReadPush(X);
    772:   PetscLogEventBegin(TAO_JacobianEval,tao,X,J,Jpre);
    773:   PetscStackPush("Tao user Jacobian(inequality) function");
    774:   (*tao->ops->computejacobianinequality)(tao,X,J,Jpre,tao->user_jac_inequalityP);
    775:   PetscStackPop;
    776:   PetscLogEventEnd(TAO_JacobianEval,tao,X,J,Jpre);
    777:   VecLockReadPop(X);
    778:   return(0);
    779: }

    781: /*@C
    782:    TaoSetJacobianEqualityRoutine - Sets the function to compute the Jacobian
    783:    (and its inverse) of the constraint function with respect to the equality variables.
    784:    Used only for pde-constrained optimization.

    786:    Logically collective on Tao

    788:    Input Parameters:
    789: +  tao  - the Tao context
    790: .  J    - Matrix used for the jacobian
    791: .  Jpre - Matrix that will be used operated on by PETSc preconditioner, can be same as J.
    792: .  func - Jacobian evaluation routine
    793: -  ctx  - [optional] user-defined context for private data for the
    794:           Jacobian evaluation routine (may be NULL)

    796:    Calling sequence of func:
    797: $    func(Tao tao,Vec x,Mat J,Mat Jpre,void *ctx);

    799: +  tao  - the Tao  context
    800: .  x    - input vector
    801: .  J    - Jacobian matrix
    802: .  Jpre - preconditioner matrix, usually the same as J
    803: -  ctx  - [optional] user-defined Jacobian context

    805:    Level: intermediate

    807: .seealso: TaoComputeJacobianEquality(), TaoSetJacobianDesignRoutine(), TaoSetEqualityDesignIS()
    808: @*/
    809: PetscErrorCode TaoSetJacobianEqualityRoutine(Tao tao, Mat J, Mat Jpre, PetscErrorCode (*func)(Tao, Vec, Mat, Mat,void*), void *ctx)
    810: {

    815:   if (J) {
    818:   }
    819:   if (Jpre) {
    822:   }
    823:   if (ctx) {
    824:     tao->user_jac_equalityP = ctx;
    825:   }
    826:   if (func) {
    827:     tao->ops->computejacobianequality = func;
    828:   }
    829:   if (J) {
    830:     PetscObjectReference((PetscObject)J);
    831:     MatDestroy(&tao->jacobian_equality);
    832:     tao->jacobian_equality = J;
    833:   }
    834:   if (Jpre) {
    835:     PetscObjectReference((PetscObject)Jpre);
    836:     MatDestroy(&tao->jacobian_equality_pre);
    837:     tao->jacobian_equality_pre=Jpre;
    838:   }
    839:   return(0);
    840: }

    842: /*@C
    843:    TaoSetJacobianInequalityRoutine - Sets the function to compute the Jacobian
    844:    (and its inverse) of the constraint function with respect to the inequality variables.
    845:    Used only for pde-constrained optimization.

    847:    Logically collective on Tao

    849:    Input Parameters:
    850: +  tao  - the Tao context
    851: .  J    - Matrix used for the jacobian
    852: .  Jpre - Matrix that will be used operated on by PETSc preconditioner, can be same as J.
    853: .  func - Jacobian evaluation routine
    854: -  ctx  - [optional] user-defined context for private data for the
    855:           Jacobian evaluation routine (may be NULL)

    857:    Calling sequence of func:
    858: $    func(Tao tao,Vec x,Mat J,Mat Jpre,void *ctx);

    860: +  tao  - the Tao  context
    861: .  x    - input vector
    862: .  J    - Jacobian matrix
    863: .  Jpre - preconditioner matrix, usually the same as J
    864: -  ctx  - [optional] user-defined Jacobian context

    866:    Level: intermediate

    868: .seealso: TaoComputeJacobianInequality(), TaoSetJacobianDesignRoutine(), TaoSetInequalityDesignIS()
    869: @*/
    870: PetscErrorCode TaoSetJacobianInequalityRoutine(Tao tao, Mat J, Mat Jpre, PetscErrorCode (*func)(Tao, Vec, Mat, Mat,void*), void *ctx)
    871: {

    876:   if (J) {
    879:   }
    880:   if (Jpre) {
    883:   }
    884:   if (ctx) {
    885:     tao->user_jac_inequalityP = ctx;
    886:   }
    887:   if (func) {
    888:     tao->ops->computejacobianinequality = func;
    889:   }
    890:   if (J) {
    891:     PetscObjectReference((PetscObject)J);
    892:     MatDestroy(&tao->jacobian_inequality);
    893:     tao->jacobian_inequality = J;
    894:   }
    895:   if (Jpre) {
    896:     PetscObjectReference((PetscObject)Jpre);
    897:     MatDestroy(&tao->jacobian_inequality_pre);
    898:     tao->jacobian_inequality_pre=Jpre;
    899:   }
    900:   return(0);
    901: }