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