Actual source code: tao_app.c

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

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


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

 19:    Input Parameters:
 20: .  comm - an MPI communiicator

 22:    Output Parameters:
 23: .  newapp - the TaoApplication structure

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

 27:    Level: beginner

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


 37:   if (TAO_APP_COOKIE==0){
 38:     info=PetscCookieRegister("TAO Application",&TAO_APP_COOKIE); CHKERRQ(info);
 39:   }

 41:   info = PetscHeaderCreate(taoapp,_p_TAOAPPLICATION,int,TAO_APP_COOKIE,-1,"TAO APP",comm,TaoAppDestroy,0); CHKERRQ(info);


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

 55:   taoapp->numbermonitors     = 0;
 56:   taoapp->numberdestroyers   = 0;
 57:   taoapp->nAddOn             = 0;

 59:   taoapp->numberoptioncheckers=0;

 61:   if (Tao_ObjectiveEval==0){
 62:     info = PetscLogEventRegister("TaoAppObjective",TAO_APP_COOKIE,&Tao_ObjectiveEval); CHKERRQ(info);
 63:     info = PetscLogEventRegister("TaoAppGradient",TAO_APP_COOKIE,&Tao_GradientEval); CHKERRQ(info);
 64:     info = PetscLogEventRegister("TaoAppHessian",TAO_APP_COOKIE,&Tao_HessianEval); CHKERRQ(info);
 65:     info = PetscLogEventRegister("TaoAppJacobian",TAO_APP_COOKIE,&Tao_JacobianEval); CHKERRQ(info);
 66:     info = PetscLogEventRegister("TaoAppFunction",TAO_APP_COOKIE,&Tao_FunctionEval); CHKERRQ(info);
 67:   }
 68:   info = TaoAppAddFiniteDifferences(taoapp); CHKERRQ(info);
 69:   info = KSPCreate(comm,&taoapp->ksp); CHKERRQ(info);
 70:   info = KSPSetFromOptions(taoapp->ksp); 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 (--((PetscObject)taoapp)->refct > 0) return(0);
 96:   if (taoapp->V){  info = VecDestroy(taoapp->V);  CHKERRQ(info); }
 97:   if (taoapp->G){  info = VecDestroy(taoapp->G);  CHKERRQ(info); }
 98:   if (taoapp->H){  info = MatDestroy(taoapp->H);  CHKERRQ(info); }
 99:   if (taoapp->HP){ info = MatDestroy(taoapp->HP); CHKERRQ(info); }
100:   if (taoapp->R){  info = VecDestroy(taoapp->R);  CHKERRQ(info); }
101:   if (taoapp->J){  info = MatDestroy(taoapp->J);  CHKERRQ(info); }
102:   if (taoapp->JP){ info = MatDestroy(taoapp->JP); CHKERRQ(info); }
103:   
104:   if (taoapp->ksp) {
105:     info = KSPDestroy(taoapp->ksp); CHKERRQ(info);
106:     taoapp->ksp=0;
107:   }
108:   for (i=0; i< taoapp->numberdestroyers; i++){
109:     info = (*taoapp->userdestroy[i])(taoapp->userctxdestroy[i]); CHKERRQ(info);
110:   }
111:   
112:   //  delete taoapp->taoappl;
113:   
114:   PetscHeaderDestroy(taoapp); 
115:   return(0);
116: }


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

125:    Collective on TAO_APPLICATION

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

131:    Level: beginner

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

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

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

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

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

171:    Collective on TAO_APPLICATION

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

177:    Level: beginner

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

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

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

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

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

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

218:    Level: intermediate


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


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

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

242:    Collective on TAO_APPLICATION

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

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

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


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

262:    Level: intermediate

264: .keywords: options, monitor, View

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

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

287:    Collective on TAO_APPLICATION

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

292:    Level: developer

294: .keywords: options, monitor, View

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


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

316:    Collective on TAO_APPLICATION

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

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

327: .    ctx - [optional] destroy context


330:    Level: intermediate

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

337: .keywords: destroy

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

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

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

363:    Collective on TAO_APPLICATION

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

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

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

377:    Level: advanced

379: .keywords: extensions

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


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

407:    Collective on TAO_APPLICATION

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

414:    Output Parameter:
415:    

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

420:    Level: advanced

422: .keywords: extensions

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

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


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

451:    Collective on TAO_APPLICATION

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

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

460:    Level: advanced

462: .keywords: extensions

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

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

495:    Collective on TAO_APPLICATION

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

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

504: .    taoapp - the TAO_APPLICATION solver context


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

511:    Level: advanced

513: .keywords: options, monitor, View

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

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

535:    Collective on TAO_APPLICATION

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

540:    Level: beginner

542: .keywords:  options

544: .seealso: TaoSetFromOptions()

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

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

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

574:    Collective on TAO_APPLICATION

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

579:    Level: intermediate

581: .keywords:  options

583: .seealso: TaoSetFromOptions()

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