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