Actual source code: tao_app.c

      1: #include "tao_app_impl.h"       /*I  "tao.h"  I*/

      3: int Tao_ObjectiveEval=0, Tao_GradientEval=0, Tao_HessianEval=0,Tao_JacobianEval=0,Tao_FunctionEval=0;
      4: int TAO_APP_COOKIE=0;

     10: /*@C
     11:   TaoApplicationCreate - Creates a TaoApplication that
     12: uses PETSc data structures.   The vectors used for gradient
     13: and other information can be a PETSc Vec.  The routines
     14: for function evaluation, and derivative information can
     15: also used PETSc arguments.

     17:    Input Parameters:
     18: .  comm - an MPI communiicator

     20:    Output Parameters:
     21: .  newapp - the TaoApplication structure

     23: .seealso TaoAppSetObjectiveAndGradientRoutine(), TaoSolveApplication(), TaoAppDestroy()

     25:    Level: beginner

     27: .keywords: Application
     28: @*/
     29: int TaoApplicationCreate(MPI_Comm comm, TAO_APPLICATION* newapp){
     30:   int info;
     31:   TAO_APPLICATION taoapp;

     35:   if (TAO_APP_COOKIE==0){
     36:     info=PetscLogClassRegister(&TAO_APP_COOKIE,"TAO Application"); CHKERRQ(info);
     37:   }

     39:   //   PetscHeaderCreate(taoapp,_p_PETSC_APPLICATION,int,TAO_APP_COOKIE,-1,"TAO DA APP",comm,TaoAppDestroy,0);
     40:   info = PetscHeaderCreate(taoapp,_p_TAOAPPLICATION,int,TAO_APP_COOKIE,-1,"TAO APP",comm,0,0); CHKERRQ(info);
     41:   info = PetscLogObjectCreate(taoapp); CHKERRQ(info);
     42:   info = PetscLogObjectMemory(taoapp, sizeof(struct _p_TAOAPPLICATION)); CHKERRQ(info);
     43:   //  taoapp->taoappl = new TaoPetscApplication(comm);

     46:   /* This part works */
     47:   taoapp->computeumfunction=0; taoapp->computegradient=0;
     48:   taoapp->computefunctiongradient=0; taoapp->computehessian=0;
     49:   taoapp->computejacobian=0; taoapp->computevfunc=0;
     50:   taoapp->computebounds=0; taoapp->boundctx=0;
     51:   taoapp->grtol=0;
     52:   taoapp->usrfctx=0; taoapp->usrfgctx=0; taoapp->usrgctx=0; taoapp->usrhctx=0;
     53:   taoapp->V=0;
     54:   taoapp->G=0; taoapp->H=0; taoapp->HP=0;
     55:   taoapp->R=0; taoapp->J=0; taoapp->JP=0;

     57:   taoapp->numbermonitors     = 0;
     58:   taoapp->numberdestroyers   = 0;
     59:   taoapp->nAddOn             = 0;

     61:   taoapp->numberoptioncheckers=0;

     63:   if (Tao_ObjectiveEval==0){
     64:     info = PetscLogEventRegister(&Tao_ObjectiveEval,"TaoAppObjective",TAO_APP_COOKIE); CHKERRQ(info);
     65:     info = PetscLogEventRegister(&Tao_GradientEval,"TaoAppGradient",TAO_APP_COOKIE); CHKERRQ(info);
     66:     info = PetscLogEventRegister(&Tao_HessianEval,"TaoAppHessian",TAO_APP_COOKIE); CHKERRQ(info);
     67:     info = PetscLogEventRegister(&Tao_JacobianEval,"TaoAppJacobian",TAO_APP_COOKIE); CHKERRQ(info);
     68:     info = PetscLogEventRegister(&Tao_FunctionEval,"TaoAppFunction",TAO_APP_COOKIE); CHKERRQ(info);
     69:   }
     70:   info = TaoAppAddFiniteDifferences(taoapp); CHKERRQ(info);
     71:   *newapp=taoapp;
     72:   return(0);
     73: }

     77: /*@
     78:   TaoAppDestroy - Destroy the PETSc application
     79: and all of the vectors and matrices associated with it.

     81:    Input Parameters:
     82: .  taoapp - the TaoApplication structure

     84: .seealso TaoApplicationCreate(), TaoDestroy()

     86:    Level: beginner

     88: .keywords: Application, Destroy
     89: @*/
     90: int TaoAppDestroy(TAO_APPLICATION taoapp){
     91:   int i,info;

     95:   if (taoapp->V){  info = VecDestroy(taoapp->V);  CHKERRQ(info); }
     96:   if (taoapp->G){  info = VecDestroy(taoapp->G);  CHKERRQ(info); }
     97:   if (taoapp->H){  info = MatDestroy(taoapp->H);  CHKERRQ(info); }
     98:   if (taoapp->HP){ info = MatDestroy(taoapp->HP); CHKERRQ(info); }
     99:   if (taoapp->R){  info = VecDestroy(taoapp->R);  CHKERRQ(info); }
    100:   if (taoapp->J){  info = MatDestroy(taoapp->J);  CHKERRQ(info); }
    101:   if (taoapp->JP){ info = MatDestroy(taoapp->JP); CHKERRQ(info); }
    102:
    103:   for (i=0; i< taoapp->numberdestroyers; i++){
    104:     info = (*taoapp->userdestroy[i])(taoapp->userctxdestroy[i]); CHKERRQ(info);
    105:   }
    106:
    107:   //  delete taoapp->taoappl;
    108:   PetscLogObjectDestroy(taoapp);
    109:   PetscHeaderDestroy(taoapp);
    110:   return(0);
    111: }

    116: /*@
    117:    TaoAppSetInitialSolutionVec - Sets the vector representing the variables
    118:    and an initial guess.

    120:    Collective on TAO_APPLICATION

    122:    Input Parameters:
    123: +  taoapp - the TAO_APPLICATION context
    124: -  xx - variable vector that stores the solution

    126:    Level: beginner

    128:    Note:
    129:    This vector will be used by the solver, so do not use it
    130:    for other purposes.  The user should destroy this vector after
    131:    solving the application.

    133:    Note:
    134:    If the user is unaware of a decent initial solution,
    135:    the vector should be set to zero.

    137:    Note:
    138:    The TAO solvers will not use the contents of this
    139:    Vec until the TaoSolve() is called.  Therefore the user
    140:    may compute an initial solution in this vector after this
    141:    routine -- but before TaoSolve().

    143: .seealso:  TaoAppGetSolutionVec(), TaoAppSetObjectiveRoutine()
    144: @*/
    145: int TaoAppSetInitialSolutionVec(TAO_APPLICATION taoapp, Vec xx){
    146:   int info;
    149:   if (xx){
    151:     PetscObjectReference((PetscObject)xx);
    152:  }
    153:   if (taoapp->V){
    154:     info=VecDestroy(taoapp->V);CHKERRQ(info);
    155:   }
    156:   taoapp->V=xx;
    157:   return(0);
    158: }

    162: /*@
    163:    TaoAppSetDefaultSolutionVec - Sets the vector representing the variables
    164:    and an initial guess.

    166:    Collective on TAO_APPLICATION

    168:    Input Parameters:
    169: +  taoapp - the TAO_APPLICATION context
    170: -  xx - variable vector that stores the solution

    172:    Level: beginner

    174:    Note:
    175:    This vector will be used by the solver, so do not use it
    176:    for other purposes.  The user should destroy this vector after
    177:    solving the application.

    179: .seealso:  TaoAppGetSolutionVec(), TaoAppSetObjectiveRoutine(), TaoAppSetInitialSolutionVec()
    180: @*/
    181: int TaoAppSetDefaultSolutionVec(TAO_APPLICATION taoapp, Vec xx){
    182:   int info;
    183:   PetscScalar zero=0.0;
    186:   if (xx){
    188:     PetscObjectReference((PetscObject)xx);
    189:  }
    190:   if (taoapp->V){
    191:     info=VecDestroy(taoapp->V);CHKERRQ(info);
    192:   }
    193:   taoapp->V=xx;
    194:   info = VecSet(xx, zero); CHKERRQ(info);
    195:   return(0);
    196: }

    200: /*@C
    201:   TaoAppGetSolutionVec - Get the vector with the
    202:   solution in the current application.

    204:    Input Parameters:
    205: .  taoapp - the application

    207:    Output Parameter:
    208: .  X - the solution vector

    210:    Note:
    211:    This vector should not be destroyed.

    213:    Level: intermediate

    216: .keywords: Application, variables
    217: @*/
    218: int TaoAppGetSolutionVec(TAO_APPLICATION taoapp, Vec *X){
    221:   if (X){
    222:     *X=taoapp->V;
    223:   }
    224:   return(0);
    225: }

    228: /* ------------ Routines to set performance monitoring options ----------- */

    232: /*@C
    233:    TaoAppSetMonitor - Sets an ADDITIONAL function that is to be used at every
    234:    iteration of the solver to display the iteration's
    235:    progress.

    237:    Collective on TAO_APPLICATION

    239:    Input Parameters:
    240: +  taoapp - the TAO_APPLICATION solver context
    241: .  mymonitor - monitoring routine
    242: -  mctx - [optional] user-defined context for private data for the
    243:           monitor routine (may be TAO_NULL)

    245:    Calling sequence of mymonitor:
    246: $     int mymonitor(TAO_APPLICATION taoapp,void *mctx)

    248: +    taoapp - the TAO_APPLICATION solver context
    249: -    mctx - [optional] monitoring context

    252:    Note:
    253:    Several different monitoring routines may be set by calling
    254:    TaoAppSetMonitor() multiple times; all will be called in the
    255:    order in which they were set.

    257:    Level: intermediate

    259: .keywords: options, monitor, View

    261: .seealso: TaoSetMonitor(), TaoAppSetDestroyRoutine()
    262: @*/
    263: int TaoAppSetMonitor(TAO_APPLICATION taoapp,int (*mymonitor)(TAO_APPLICATION,void*),void *mctx)
    264: {
    267:   if (mymonitor){
    268:     if (taoapp->numbermonitors >= MAX_TAO_MONITORS) {
    269:       SETERRQ(1,"Too many monitors set");
    270:     }
    271:     taoapp->monitor[taoapp->numbermonitors]           = mymonitor;
    272:     taoapp->monitorcontext[taoapp->numbermonitors++]  = (void*)mctx;
    273:   }
    274:   return(0);
    275: }

    279: /*@
    280:    TaoAppMonitor - Apply the monitor functions for a TAO_APPLICATION object.

    282:    Collective on TAO_APPLICATION

    284:    Input Parameters:
    285: .  taoapp - the TAO_APPLICATION structure

    287:    Level: developer

    289: .keywords: options, monitor, View

    291: .seealso: TaoAppSetMonitor()
    292: @*/
    293: int TaoAppMonitor(TAO_APPLICATION taoapp){
    294:   int i,info;
    297:   for ( i=0; i<taoapp->numbermonitors; i++ ) {
    298:     info = (*taoapp->monitor[i])(taoapp,taoapp->monitorcontext[i]);CHKERRQ(info);
    299:   }
    300:   return(0);
    301: }

    304: /* ------------ Routines to called when destroying this application ----------- */
    307: /*@C
    308:    TaoAppSetDestroyRoutine - Sets an ADDITIONAL function that will be called when
    309:    this application is destroyed.

    311:    Collective on TAO_APPLICATION

    313:    Input Parameters:
    314: +  taoapp - the TAO_APPLICATION solver context
    315: .  destroy - function pointer
    316: -  ctx - [optional] user-defined context for private data for the
    317:           destroy routine (may be TAO_NULL)

    319:    Calling sequence of destroy:
    320: $     int mydestroy(void *ctx)

    322: .    ctx - [optional] destroy context

    325:    Level: intermediate

    327:    Note:
    328:    This routine is often used to destroy structures used by monitors and
    329:    function evaluations.  This routine may also be used to shut down other packages
    330:    such as ADIC.

    332: .keywords: destroy

    334: .seealso: TaoAppSetMonitor(), TaoAppSetHessianRoutine(), TaoAppDestroy()
    335: @*/
    336: int TaoAppSetDestroyRoutine(TAO_APPLICATION taoapp,int (*destroy)(void*),void *ctx)
    337: {
    340:   if (destroy){
    341:     if (taoapp->numberdestroyers >= MAX_TAO_USER_DESTROY) {
    342:       SETERRQ(1,"TAO ERRROR: Too many TAO APPLICATION destroy routines set");
    343:     }
    344:
    345:     taoapp->userdestroy[taoapp->numberdestroyers]           = destroy;
    346:     taoapp->userctxdestroy[taoapp->numberdestroyers++]      = ctx;
    347:   }
    348:   return(0);
    349: }

    351: /* ------------ Routines to extend TaoApp ----------- */

    355: /*@
    356:    TaoAppAddObject -  add an object from to the Tao Application.

    358:    Collective on TAO_APPLICATION

    360:    Input Parameters:
    361: +  taoapp - the TAO_APPLICATION solver context
    362: .  key - string used to ID this object
    363: -  ctx - user-defined context for private data

    365:    Output Paramter:
    366: .  id - ignored
    367:

    369:    Note:
    370:    This routine can be used to extend the functionality of this object

    372:    Level: advanced

    374: .keywords: extensions

    376: .seealso: TaoAppQueryForObject()
    377: @*/
    378: int TaoAppAddObject(TAO_APPLICATION taoapp, char *key, void *ctx, int *id)
    379: {
    380:   int info;
    383:   if (ctx){
    384:     if (taoapp->nAddOn >= MAX_TAOAPP_ADDON) {
    385:       SETERRQ(1,"Too many TaoObject added on");
    386:     }
    387:     taoapp->TaoAppCtx[taoapp->nAddOn].ctx = ctx;
    388:     info=PetscStrncpy(taoapp->TaoAppCtx[taoapp->nAddOn].key , key, MAX_TAO_KEY_LENGTH); CHKERRQ(info);
    389:     taoapp->TaoAppCtx[taoapp->nAddOn].id = taoapp->nAddOn;
    390:     *id=taoapp->TaoAppCtx[taoapp->nAddOn].id;
    391:     taoapp->nAddOn++;
    392:   }
    393:   return(0);
    394: }

    399: /*@
    400:    TaoAppQueryForObject -  query the TAO Application for an object

    402:    Collective on TAO_APPLICATION

    404:    Input Parameters:
    405: +  taoapp - the TAO_APPLICATION solver context
    406: .  key - string used to ID this object
    407: -  ctx - user-defined context for private data

    409:    Output Parameter:
    410:

    412:    Note:
    413:    This routine can be used to extend the functionality of this object

    415:    Level: advanced

    417: .keywords: extensions

    419: .seealso: TaoAppAddObject()
    420: @*/
    421: int TaoAppQueryForObject(TAO_APPLICATION taoapp, char *key, void **ctx)
    422: {
    423:   int i,n,info;
    424:   PetscTruth flag=PETSC_FALSE;

    428:   n=taoapp->nAddOn;
    429:   *ctx=0;
    430:   for (i=0;i<n;i++){
    431:     info=PetscStrncmp(taoapp->TaoAppCtx[i].key,key,MAX_TAOAPP_ADDON,&flag); CHKERRQ(info);
    432:     if (flag==PETSC_TRUE){
    433:       *ctx=taoapp->TaoAppCtx[i].ctx;
    434:       break;
    435:     }
    436:   }
    437:   return(0);
    438: }

    443: /*@
    444:    TaoAppQueryRemoveObject -  add an object from to the Tao Application.

    446:    Collective on TAO_APPLICATION

    448:    Input Parameters:
    449: +  taoapp - the TAO_APPLICATION solver context
    450: -  key - string used to ID this object

    452:    Note:
    453:    This routine can be used to extend the functionality of this object

    455:    Level: advanced

    457: .keywords: extensions

    459: .seealso: TaoAppQueryForObject()
    460: @*/
    461: int TaoAppQueryRemoveObject(TAO_APPLICATION taoapp, char *key)
    462: {
    463:   int i,n,info;
    464:   PetscTruth flag;
    467:   n=taoapp->nAddOn;
    468:   for (i=0;i<n;i++){
    469:     info=PetscStrncmp(taoapp->TaoAppCtx[i].key,key,MAX_TAO_KEY_LENGTH,&flag); CHKERRQ(info);
    470:     if (flag==PETSC_TRUE){
    471:       if (n>0){
    472:         taoapp->TaoAppCtx[i].ctx=taoapp->TaoAppCtx[n-1].ctx;
    473:         taoapp->TaoAppCtx[i].id=taoapp->TaoAppCtx[n-1].id;
    474:         info=PetscStrncpy(taoapp->TaoAppCtx[i].key,taoapp->TaoAppCtx[n-1].key,MAX_TAO_KEY_LENGTH);
    475:         CHKERRQ(info);
    476:       }
    477:       taoapp->nAddOn--;
    478:       break;
    479:     }
    480:   }
    481:   return(0);
    482: }

    486: /*@C
    487:    TaoAppSetOptionsRoutine - Sets an ADDITIONAL function that is to be called
    488:    during TaoSetFromOptions().

    490:    Collective on TAO_APPLICATION

    492:    Input Parameters:
    493: +  tao - the TAO_APPLICATION solver context
    494: -  options -  routine the checks options

    496:    Calling sequence of options:
    497: $     int myoptions(TAO_APPLICATION taoapp)

    499: .    taoapp - the TAO_APPLICATION solver context

    502:    Note:
    503:    Several different options routines may be set by calling
    504:    this routine.

    506:    Level: advanced

    508: .keywords: options, monitor, View

    510: .seealso: TaoAppSetFromOptions()
    511: @*/
    512: int TaoAppSetOptionsRoutine(TAO_APPLICATION taoapp,int (*options)(TAO_APPLICATION) )
    513: {
    516:   if (options){
    517:     if (taoapp->numberoptioncheckers >= MAX_TAO_MONITORS) {
    518:       SETERRQ(1,"Too many options checkers set");
    519:     }
    520:     taoapp->checkoptions[taoapp->numberoptioncheckers++] = options;
    521:   }
    522:   return(0);
    523: }

    527: /*@
    528:   TaoAppSetFromOptions - Sets various TAO parameters from user options

    530:    Collective on TAO_APPLICATION

    532:    Input Parameters:
    533: .  taoapp - the TAO Application

    535:    Level: beginner

    537: .keywords:  options

    539: .seealso: TaoSetFromOptions()

    541: @*/
    542: int TaoAppSetFromOptions(TAO_APPLICATION taoapp){
    543:   int i,info;
    544:   const char *prefix=0;
    545:   MPI_Comm comm;
    546:   PetscTruth flg1;

    550:   info = PetscObjectGetOptionsPrefix((PetscObject)taoapp,&prefix); CHKERRQ(info);
    551:   info = PetscObjectGetComm((PetscObject)taoapp,&comm);CHKERRQ(info);
    552:   info = PetscOptionsBegin(comm,prefix,"TAO PETSC APPLICATIONS ","solver");CHKERRQ(info);
    553:   info = PetscOptionsReal("-taoapp_grtol","the relative tolerance","TaoAppSetRelativeTolerance",
    554:                           taoapp->grtol,&taoapp->grtol,&flg1);CHKERRQ(info);
    555:   for (i=0;i<taoapp->numberoptioncheckers;i++){
    556:     info = (*taoapp->checkoptions[i])(taoapp);CHKERRQ(info);
    557:   }
    558:   info = PetscOptionsEnd(); CHKERRQ(info);
    559:   return(0);
    560: }