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:   info = KSPCreate(comm,&taoapp->ksp); CHKERRQ(info);
 72:   info = KSPSetFromOptions(taoapp->ksp); CHKERRQ(info);
 73:   *newapp=taoapp;
 74:   return(0);
 75: }

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

 83:    Input Parameters:
 84: .  taoapp - the TaoApplication structure

 86: .seealso TaoApplicationCreate(), TaoDestroy()

 88:    Level: beginner

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

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


122: /*@
123:    TaoAppSetInitialSolutionVec - Sets the vector representing the variables
124:    and an initial guess.

126:    Collective on TAO_APPLICATION

128:    Input Parameters:
129: +  taoapp - the TAO_APPLICATION context
130: -  xx - variable vector that stores the solution

132:    Level: beginner

134:    Note: 
135:    This vector will be used by the solver, so do not use it
136:    for other purposes.  The user should destroy this vector after
137:    solving the application.

139:    Note:  
140:    If the user is unaware of a decent initial solution,
141:    the vector should be set to zero.

143:    Note:  
144:    The TAO solvers will not use the contents of this 
145:    Vec until the TaoSolve() is called.  Therefore the user
146:    may compute an initial solution in this vector after this
147:    routine -- but before TaoSolve().

149: .seealso:  TaoAppGetSolutionVec(), TaoAppSetObjectiveRoutine()
150: @*/
151: int TaoAppSetInitialSolutionVec(TAO_APPLICATION taoapp, Vec xx){
152:   int info;
155:   if (xx){
157:     PetscObjectReference((PetscObject)xx);
158:  }
159:   if (taoapp->V){
160:     info=VecDestroy(taoapp->V);CHKERRQ(info); 
161:   }  
162:   taoapp->V=xx;
163:   return(0);
164: }

168: /*@
169:    TaoAppSetDefaultSolutionVec - Sets the vector representing the variables
170:    and an initial guess.

172:    Collective on TAO_APPLICATION

174:    Input Parameters:
175: +  taoapp - the TAO_APPLICATION context
176: -  xx - variable vector that stores the solution

178:    Level: beginner

180:    Note: 
181:    This vector will be used by the solver, so do not use it
182:    for other purposes.  The user should destroy this vector after
183:    solving the application.

185: .seealso:  TaoAppGetSolutionVec(), TaoAppSetObjectiveRoutine(), TaoAppSetInitialSolutionVec()
186: @*/
187: int TaoAppSetDefaultSolutionVec(TAO_APPLICATION taoapp, Vec xx){
188:   int info;
189:   PetscScalar zero=0.0;
192:   if (xx){
194:     PetscObjectReference((PetscObject)xx);
195:  }
196:   if (taoapp->V){
197:     info=VecDestroy(taoapp->V);CHKERRQ(info); 
198:   }  
199:   taoapp->V=xx;
200:   info = VecSet(xx, zero); CHKERRQ(info);
201:   return(0);
202: }

206: /*@
207:   TaoAppGetSolutionVec - Get the vector with the
208:   solution in the current application.

210:    Input Parameters:
211: .  taoapp - the application

213:    Output Parameter:
214: .  X - the solution vector

216:    Note: 
217:    This vector should not be destroyed.

219:    Level: intermediate


222: .keywords: Application, variables
223: @*/
224: int TaoAppGetSolutionVec(TAO_APPLICATION taoapp, Vec *X){
227:   if (X){
228:     *X=taoapp->V;
229:   }
230:   return(0);
231: }


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

238: /*@C
239:    TaoAppSetMonitor - Sets an ADDITIONAL function that is to be used at every
240:    iteration of the solver to display the iteration's 
241:    progress.   

243:    Collective on TAO_APPLICATION

245:    Input Parameters:
246: +  taoapp - the TAO_APPLICATION solver context
247: .  mymonitor - monitoring routine
248: -  mctx - [optional] user-defined context for private data for the 
249:           monitor routine (may be TAO_NULL)

251:    Calling sequence of mymonitor:
252: $     int mymonitor(TAO_APPLICATION taoapp,void *mctx)

254: +    taoapp - the TAO_APPLICATION solver context
255: -    mctx - [optional] monitoring context


258:    Note: 
259:    Several different monitoring routines may be set by calling
260:    TaoAppSetMonitor() multiple times; all will be called in the 
261:    order in which they were set.

263:    Level: intermediate

265: .keywords: options, monitor, View

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

285: /*@
286:    TaoAppMonitor - Apply the monitor functions for a TAO_APPLICATION object.

288:    Collective on TAO_APPLICATION

290:    Input Parameters:
291: .  taoapp - the TAO_APPLICATION structure

293:    Level: developer

295: .keywords: options, monitor, View

297: .seealso: TaoAppSetMonitor()
298: @*/
299: int TaoAppMonitor(TAO_APPLICATION taoapp){
300:   int i,info;
303:   for ( i=0; i<taoapp->numbermonitors; i++ ) {
304:     info = (*taoapp->monitor[i])(taoapp,taoapp->monitorcontext[i]);CHKERRQ(info);
305:   }
306:   return(0);
307: }


310: /* ------------ Routines to called when destroying this application ----------- */
313: /*@C
314:    TaoAppSetDestroyRoutine - Sets an ADDITIONAL function that will be called when
315:    this application is destroyed.

317:    Collective on TAO_APPLICATION

319:    Input Parameters:
320: +  taoapp - the TAO_APPLICATION solver context
321: .  destroy - function pointer
322: -  ctx - [optional] user-defined context for private data for the 
323:           destroy routine (may be TAO_NULL)

325:    Calling sequence of destroy:
326: $     int mydestroy(void *ctx)

328: .    ctx - [optional] destroy context


331:    Level: intermediate

333:    Note:  
334:    This routine is often used to destroy structures used by monitors and 
335:    function evaluations.  This routine may also be used to shut down other packages
336:    such as ADIC.

338: .keywords: destroy

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

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

361: /*@
362:    TaoAppAddObject -  add an object from to the Tao Application.

364:    Collective on TAO_APPLICATION

366:    Input Parameters:
367: +  taoapp - the TAO_APPLICATION solver context
368: .  key - string used to ID this object
369: -  ctx - user-defined context for private data

371:    Output Paramter:
372: .  id - ignored
373:    

375:    Note: 
376:    This routine can be used to extend the functionality of this object

378:    Level: advanced

380: .keywords: extensions

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


405: /*@
406:    TaoAppQueryForObject -  query the TAO Application for an object

408:    Collective on TAO_APPLICATION

410:    Input Parameters:
411: +  taoapp - the TAO_APPLICATION solver context
412: .  key - string used to ID this object
413: -  ctx - user-defined context for private data

415:    Output Parameter:
416:    

418:    Note: 
419:    This routine can be used to extend the functionality of this object

421:    Level: advanced

423: .keywords: extensions

425: .seealso: TaoAppAddObject()
426: @*/
427: int TaoAppQueryForObject(TAO_APPLICATION taoapp, char *key, void **ctx)
428: {
429:   int i,n,info;
430:   PetscTruth flag=PETSC_FALSE;

434:   n=taoapp->nAddOn;
435:   *ctx=0;
436:   for (i=0;i<n;i++){
437:     info=PetscStrncmp(taoapp->TaoAppCtx[i].key,key,MAX_TAOAPP_ADDON,&flag); CHKERRQ(info);
438:     if (flag==PETSC_TRUE){
439:       *ctx=taoapp->TaoAppCtx[i].ctx;
440:       break;
441:     }
442:   }
443:   return(0);
444: }


449: /*@
450:    TaoAppQueryRemoveObject -  add an object from to the Tao Application.

452:    Collective on TAO_APPLICATION

454:    Input Parameters:
455: +  taoapp - the TAO_APPLICATION solver context
456: -  key - string used to ID this object

458:    Note: 
459:    This routine can be used to extend the functionality of this object

461:    Level: advanced

463: .keywords: extensions

465: .seealso: TaoAppQueryForObject()
466: @*/
467: int TaoAppQueryRemoveObject(TAO_APPLICATION taoapp, char *key)
468: {
469:   int i,n,info;
470:   PetscTruth flag;
473:   n=taoapp->nAddOn;
474:   for (i=0;i<n;i++){
475:     info=PetscStrncmp(taoapp->TaoAppCtx[i].key,key,MAX_TAO_KEY_LENGTH,&flag); CHKERRQ(info);
476:     if (flag==PETSC_TRUE){
477:       if (n>0){
478:         taoapp->TaoAppCtx[i].ctx=taoapp->TaoAppCtx[n-1].ctx;
479:         taoapp->TaoAppCtx[i].id=taoapp->TaoAppCtx[n-1].id;
480:         info=PetscStrncpy(taoapp->TaoAppCtx[i].key,taoapp->TaoAppCtx[n-1].key,MAX_TAO_KEY_LENGTH); 
481:         CHKERRQ(info);
482:       }
483:       taoapp->nAddOn--;
484:       break;
485:     }
486:   }
487:   return(0);
488: }

492: /*@C
493:    TaoAppSetOptionsRoutine - Sets an ADDITIONAL function that is to be called
494:    during TaoSetFromOptions().

496:    Collective on TAO_APPLICATION

498:    Input Parameters:
499: +  tao - the TAO_APPLICATION solver context
500: -  options -  routine the checks options

502:    Calling sequence of options:
503: $     int myoptions(TAO_APPLICATION taoapp)

505: .    taoapp - the TAO_APPLICATION solver context


508:    Note: 
509:    Several different options routines may be set by calling
510:    this routine.

512:    Level: advanced

514: .keywords: options, monitor, View

516: .seealso: TaoAppSetFromOptions()
517: @*/
518: int TaoAppSetOptionsRoutine(TAO_APPLICATION taoapp,int (*options)(TAO_APPLICATION) )
519: {
522:   if (options){
523:     if (taoapp->numberoptioncheckers >= MAX_TAO_MONITORS) {
524:       SETERRQ(1,"Too many options checkers set");
525:     }    
526:     taoapp->checkoptions[taoapp->numberoptioncheckers++] = options;
527:   }
528:   return(0);
529: }

533: /*@
534:   TaoAppSetFromOptions - Sets various TAO parameters from user options

536:    Collective on TAO_APPLICATION

538:    Input Parameters:
539: .  taoapp - the TAO Application

541:    Level: beginner

543: .keywords:  options

545: .seealso: TaoSetFromOptions()

547: @*/
548: int TaoAppSetFromOptions(TAO_APPLICATION taoapp){
549:   int i,info;
550:   const char *prefix=0;
551:   MPI_Comm comm;
552:   PetscTruth flg1;

556:   info = PetscObjectGetOptionsPrefix((PetscObject)taoapp,&prefix); CHKERRQ(info);
557:   info = PetscObjectGetComm((PetscObject)taoapp,&comm);CHKERRQ(info);
558:   info = PetscOptionsBegin(comm,prefix,"TAO PETSC APPLICATIONS ","solver");CHKERRQ(info);
559:   info = PetscOptionsReal("-taoapp_grtol","the relative tolerance","TaoAppSetRelativeTolerance",
560:                           taoapp->grtol,&taoapp->grtol,&flg1);CHKERRQ(info);
561:   for (i=0;i<taoapp->numberoptioncheckers;i++){
562:     info = (*taoapp->checkoptions[i])(taoapp);CHKERRQ(info);
563:   }
564:   info = KSPSetFromOptions(taoapp->ksp);CHKERRQ(info);
565:   info = PetscOptionsEnd(); CHKERRQ(info);
566:   return(0);
567: }

571: int TaoAppGetKSP(TAO_APPLICATION taoapp, KSP *ksp){
572: /*@C
573:   TaoAppGetKSP - Gets the linear solver used by the optimization application

575:    Collective on TAO_APPLICATION

577:    Input Parameters:
578: .  taoapp - the TAO Application

580:    Level: intermediate

582: .keywords:  options

584: .seealso: TaoSetFromOptions()

586: @*/
589:   if (ksp){
590:     *ksp=taoapp->ksp;
591:   }
592:   return(0);
593: }