Actual source code: ts.c

  1: #define PETSCTS_DLL

 3:  #include private/tsimpl.h

  5: /* Logging support */
  6: PetscCookie  TS_COOKIE;
  7: PetscLogEvent  TS_Step, TS_PseudoComputeTimeStep, TS_FunctionEval, TS_JacobianEval;

 11: /*
 12:   TSSetTypeFromOptions - Sets the type of ts from user options.

 14:   Collective on TS

 16:   Input Parameter:
 17: . ts - The ts

 19:   Level: intermediate

 21: .keywords: TS, set, options, database, type
 22: .seealso: TSSetFromOptions(), TSSetType()
 23: */
 24: static PetscErrorCode TSSetTypeFromOptions(TS ts)
 25: {
 26:   PetscTruth     opt;
 27:   const char     *defaultType;
 28:   char           typeName[256];

 32:   if (((PetscObject)ts)->type_name) {
 33:     defaultType = ((PetscObject)ts)->type_name;
 34:   } else {
 35:     defaultType = TSEULER;
 36:   }

 38:   if (!TSRegisterAllCalled) {TSRegisterAll(PETSC_NULL);}
 39:   PetscOptionsList("-ts_type", "TS method"," TSSetType", TSList, defaultType, typeName, 256, &opt);
 40:   if (opt) {
 41:     TSSetType(ts, typeName);
 42:   } else {
 43:     TSSetType(ts, defaultType);
 44:   }
 45:   return(0);
 46: }

 50: /*@
 51:    TSSetFromOptions - Sets various TS parameters from user options.

 53:    Collective on TS

 55:    Input Parameter:
 56: .  ts - the TS context obtained from TSCreate()

 58:    Options Database Keys:
 59: +  -ts_type <type> - TSEULER, TSBEULER, TSSUNDIALS, TSPSEUDO, TSCRANK_NICHOLSON
 60: .  -ts_max_steps maxsteps - maximum number of time-steps to take
 61: .  -ts_max_time time - maximum time to compute to
 62: .  -ts_dt dt - initial time step
 63: .  -ts_monitor - print information at each timestep
 64: -  -ts_monitor_draw - plot information at each timestep

 66:    Level: beginner

 68: .keywords: TS, timestep, set, options, database

 70: .seealso: TSGetType()
 71: @*/
 72: PetscErrorCode  TSSetFromOptions(TS ts)
 73: {
 74:   PetscReal               dt;
 75:   PetscTruth              opt,flg;
 76:   PetscErrorCode          ierr;
 77:   PetscViewerASCIIMonitor monviewer;
 78:   char                    monfilename[PETSC_MAX_PATH_LEN];

 82:   PetscOptionsBegin(((PetscObject)ts)->comm, ((PetscObject)ts)->prefix, "Time step options", "TS");

 84:     /* Handle generic TS options */
 85:     PetscOptionsInt("-ts_max_steps","Maximum number of time steps","TSSetDuration",ts->max_steps,&ts->max_steps,PETSC_NULL);
 86:     PetscOptionsReal("-ts_max_time","Time to run to","TSSetDuration",ts->max_time,&ts->max_time,PETSC_NULL);
 87:     PetscOptionsReal("-ts_init_time","Initial time","TSSetInitialTime", ts->ptime, &ts->ptime, PETSC_NULL);
 88:     PetscOptionsReal("-ts_dt","Initial time step","TSSetInitialTimeStep",ts->initial_time_step,&dt,&opt);
 89:     if (opt) {
 90:       ts->initial_time_step = ts->time_step = dt;
 91:     }

 93:     /* Monitor options */
 94:     PetscOptionsString("-ts_monitor","Monitor timestep size","TSMonitorDefault","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);
 95:     if (flg) {
 96:       PetscViewerASCIIMonitorCreate(((PetscObject)ts)->comm,monfilename,((PetscObject)ts)->tablevel,&monviewer);
 97:       TSMonitorSet(ts,TSMonitorDefault,monviewer,(PetscErrorCode (*)(void*))PetscViewerASCIIMonitorDestroy);
 98:     }
 99:     opt  = PETSC_FALSE;
100:     PetscOptionsTruth("-ts_monitor_draw","Monitor timestep size graphically","TSMonitorLG",opt,&opt,PETSC_NULL);
101:     if (opt) {
102:       TSMonitorSet(ts,TSMonitorLG,PETSC_NULL,PETSC_NULL);
103:     }
104:     opt  = PETSC_FALSE;
105:     PetscOptionsTruth("-ts_monitor_solution","Monitor solution graphically","TSMonitorSolution",opt,&opt,PETSC_NULL);
106:     if (opt) {
107:       TSMonitorSet(ts,TSMonitorSolution,PETSC_NULL,PETSC_NULL);
108:     }

110:     /* Handle TS type options */
111:     TSSetTypeFromOptions(ts);

113:     /* Handle specific TS options */
114:     if (ts->ops->setfromoptions) {
115:       (*ts->ops->setfromoptions)(ts);
116:     }
117:   PetscOptionsEnd();

119:   /* Handle subobject options */
120:   switch(ts->problem_type) {
121:     /* Should check for implicit/explicit */
122:   case TS_LINEAR:
123:     if (ts->ksp) {
124:       KSPSetOperators(ts->ksp,ts->Arhs,ts->B,DIFFERENT_NONZERO_PATTERN);
125:       KSPSetFromOptions(ts->ksp);
126:     }
127:     break;
128:   case TS_NONLINEAR:
129:     if (ts->snes) {
130:       /* this is a bit of a hack, but it gets the matrix information into SNES earlier
131:          so that SNES and KSP have more information to pick reasonable defaults
132:          before they allow users to set options
133:        * If ts->A has been set at this point, we are probably using the implicit form
134:          and Arhs will never be used. */
135:       SNESSetJacobian(ts->snes,ts->A?ts->A:ts->Arhs,ts->B,0,ts);
136:       SNESSetFromOptions(ts->snes);
137:     }
138:     break;
139:   default:
140:     SETERRQ1(PETSC_ERR_ARG_WRONG, "Invalid problem type: %d", (int)ts->problem_type);
141:   }

143:   return(0);
144: }

146: #undef  __FUNCT__
148: /*@
149:   TSViewFromOptions - This function visualizes the ts based upon user options.

151:   Collective on TS

153:   Input Parameter:
154: . ts - The ts

156:   Level: intermediate

158: .keywords: TS, view, options, database
159: .seealso: TSSetFromOptions(), TSView()
160: @*/
161: PetscErrorCode  TSViewFromOptions(TS ts,const char title[])
162: {
163:   PetscViewer    viewer;
164:   PetscDraw      draw;
165:   PetscTruth     opt = PETSC_FALSE;
166:   char           fileName[PETSC_MAX_PATH_LEN];

170:   PetscOptionsGetString(((PetscObject)ts)->prefix, "-ts_view", fileName, PETSC_MAX_PATH_LEN, &opt);
171:   if (opt && !PetscPreLoadingOn) {
172:     PetscViewerASCIIOpen(((PetscObject)ts)->comm,fileName,&viewer);
173:     TSView(ts, viewer);
174:     PetscViewerDestroy(viewer);
175:   }
176:   opt = PETSC_FALSE;
177:   PetscOptionsGetTruth(((PetscObject)ts)->prefix, "-ts_view_draw", &opt,PETSC_NULL);
178:   if (opt) {
179:     PetscViewerDrawOpen(((PetscObject)ts)->comm, 0, 0, 0, 0, 300, 300, &viewer);
180:     PetscViewerDrawGetDraw(viewer, 0, &draw);
181:     if (title) {
182:       PetscDrawSetTitle(draw, (char *)title);
183:     } else {
184:       PetscObjectName((PetscObject)ts);
185:       PetscDrawSetTitle(draw, ((PetscObject)ts)->name);
186:     }
187:     TSView(ts, viewer);
188:     PetscViewerFlush(viewer);
189:     PetscDrawPause(draw);
190:     PetscViewerDestroy(viewer);
191:   }
192:   return(0);
193: }

197: /*@
198:    TSComputeRHSJacobian - Computes the Jacobian matrix that has been
199:       set with TSSetRHSJacobian().

201:    Collective on TS and Vec

203:    Input Parameters:
204: +  ts - the TS context
205: .  t - current timestep
206: -  x - input vector

208:    Output Parameters:
209: +  A - Jacobian matrix
210: .  B - optional preconditioning matrix
211: -  flag - flag indicating matrix structure

213:    Notes: 
214:    Most users should not need to explicitly call this routine, as it 
215:    is used internally within the nonlinear solvers. 

217:    See KSPSetOperators() for important information about setting the
218:    flag parameter.

220:    TSComputeJacobian() is valid only for TS_NONLINEAR

222:    Level: developer

224: .keywords: SNES, compute, Jacobian, matrix

226: .seealso:  TSSetRHSJacobian(), KSPSetOperators()
227: @*/
228: PetscErrorCode  TSComputeRHSJacobian(TS ts,PetscReal t,Vec X,Mat *A,Mat *B,MatStructure *flg)
229: {

236:   if (ts->problem_type != TS_NONLINEAR) {
237:     SETERRQ(PETSC_ERR_ARG_WRONG,"For TS_NONLINEAR only");
238:   }
239:   if (ts->ops->rhsjacobian) {
240:     PetscLogEventBegin(TS_JacobianEval,ts,X,*A,*B);
241:     *flg = DIFFERENT_NONZERO_PATTERN;
242:     PetscStackPush("TS user Jacobian function");
243:     (*ts->ops->rhsjacobian)(ts,t,X,A,B,flg,ts->jacP);
244:     PetscStackPop;
245:     PetscLogEventEnd(TS_JacobianEval,ts,X,*A,*B);
246:     /* make sure user returned a correct Jacobian and preconditioner */
249:   } else {
250:     MatAssemblyBegin(*A,MAT_FINAL_ASSEMBLY);
251:     MatAssemblyEnd(*A,MAT_FINAL_ASSEMBLY);
252:     if (*A != *B) {
253:       MatAssemblyBegin(*B,MAT_FINAL_ASSEMBLY);
254:       MatAssemblyEnd(*B,MAT_FINAL_ASSEMBLY);
255:     }
256:   }
257:   return(0);
258: }

262: /*@
263:    TSComputeRHSFunction - Evaluates the right-hand-side function. 

265:    Collective on TS and Vec

267:    Input Parameters:
268: +  ts - the TS context
269: .  t - current time
270: -  x - state vector

272:    Output Parameter:
273: .  y - right hand side

275:    Note:
276:    Most users should not need to explicitly call this routine, as it
277:    is used internally within the nonlinear solvers.

279:    If the user did not provide a function but merely a matrix,
280:    this routine applies the matrix.

282:    Level: developer

284: .keywords: TS, compute

286: .seealso: TSSetRHSFunction(), TSComputeIFunction()
287: @*/
288: PetscErrorCode TSComputeRHSFunction(TS ts,PetscReal t,Vec x,Vec y)
289: {


297:   PetscLogEventBegin(TS_FunctionEval,ts,x,y,0);
298:   if (ts->ops->rhsfunction) {
299:     PetscStackPush("TS user right-hand-side function");
300:     (*ts->ops->rhsfunction)(ts,t,x,y,ts->funP);
301:     PetscStackPop;
302:   } else {
303:     if (ts->ops->rhsmatrix) { /* assemble matrix for this timestep */
304:       MatStructure flg;
305:       PetscStackPush("TS user right-hand-side matrix function");
306:       (*ts->ops->rhsmatrix)(ts,t,&ts->Arhs,&ts->B,&flg,ts->jacP);
307:       PetscStackPop;
308:     }
309:     MatMult(ts->Arhs,x,y);
310:   }

312:   PetscLogEventEnd(TS_FunctionEval,ts,x,y,0);

314:   return(0);
315: }

319: /*@
320:    TSComputeIFunction - Evaluates the DAE residual written in implicit form F(t,X,Xdot)=0

322:    Collective on TS and Vec

324:    Input Parameters:
325: +  ts - the TS context
326: .  t - current time
327: .  X - state vector
328: -  Xdot - time derivative of state vector

330:    Output Parameter:
331: .  Y - right hand side

333:    Note:
334:    Most users should not need to explicitly call this routine, as it
335:    is used internally within the nonlinear solvers.

337:    If the user did did not write their equations in implicit form, this
338:    function recasts them in implicit form.

340:    Level: developer

342: .keywords: TS, compute

344: .seealso: TSSetIFunction(), TSComputeRHSFunction()
345: @*/
346: PetscErrorCode TSComputeIFunction(TS ts,PetscReal t,Vec X,Vec Xdot,Vec Y)
347: {


356:   PetscLogEventBegin(TS_FunctionEval,ts,X,Xdot,Y);
357:   if (ts->ops->ifunction) {
358:     PetscStackPush("TS user implicit function");
359:     (*ts->ops->ifunction)(ts,t,X,Xdot,Y,ts->funP);
360:     PetscStackPop;
361:   } else {
362:     if (ts->ops->rhsfunction) {
363:       PetscStackPush("TS user right-hand-side function");
364:       (*ts->ops->rhsfunction)(ts,t,X,Y,ts->funP);
365:       PetscStackPop;
366:     } else {
367:       if (ts->ops->rhsmatrix) { /* assemble matrix for this timestep */
368:         MatStructure flg;
369:         /* Note: flg is not being used.
370:            For it to be useful, we'd have to cache it and then apply it in TSComputeIJacobian.
371:         */
372:         PetscStackPush("TS user right-hand-side matrix function");
373:         (*ts->ops->rhsmatrix)(ts,t,&ts->Arhs,&ts->B,&flg,ts->jacP);
374:         PetscStackPop;
375:       }
376:       MatMult(ts->Arhs,X,Y);
377:     }

379:     /* Convert to implicit form: F(X,Xdot) = Alhs * Xdot - Frhs(X) */
380:     if (ts->Alhs) {
381:       if (ts->ops->lhsmatrix) {
382:         MatStructure flg;
383:         PetscStackPush("TS user left-hand-side matrix function");
384:         (*ts->ops->lhsmatrix)(ts,t,&ts->Alhs,PETSC_NULL,&flg,ts->jacP);
385:         PetscStackPop;
386:       }
387:       VecScale(Y,-1.);
388:       MatMultAdd(ts->Alhs,Xdot,Y,Y);
389:     } else {
390:       VecAYPX(Y,-1,Xdot);
391:     }
392:   }
393:   PetscLogEventEnd(TS_FunctionEval,ts,X,Xdot,Y);
394:   return(0);
395: }

399: /*@
400:    TSComputeIJacobian - Evaluates the Jacobian of the DAE

402:    Collective on TS and Vec

404:    Input
405:       Input Parameters:
406: +  ts - the TS context
407: .  t - current timestep
408: .  X - state vector
409: .  Xdot - time derivative of state vector
410: -  shift - shift to apply, see note below

412:    Output Parameters:
413: +  A - Jacobian matrix
414: .  B - optional preconditioning matrix
415: -  flag - flag indicating matrix structure

417:    Notes:
418:    If F(t,X,Xdot)=0 is the DAE, the required Jacobian is

420:    dF/dX + shift*dF/dXdot

422:    Most users should not need to explicitly call this routine, as it
423:    is used internally within the nonlinear solvers.

425:    TSComputeIJacobian() is valid only for TS_NONLINEAR

427:    Level: developer

429: .keywords: TS, compute, Jacobian, matrix

431: .seealso:  TSSetIJacobian()
432: @*/
433: PetscErrorCode  TSComputeIJacobian(TS ts,PetscReal t,Vec X,Vec Xdot,PetscReal shift,Mat *A,Mat *B,MatStructure *flg)
434: {


447:   *flg = SAME_NONZERO_PATTERN;  /* In case it we're solving a linear problem in which case it wouldn't get initialized below. */
448:   PetscLogEventBegin(TS_JacobianEval,ts,X,*A,*B);
449:   if (ts->ops->ijacobian) {
450:     PetscStackPush("TS user implicit Jacobian");
451:     (*ts->ops->ijacobian)(ts,t,X,Xdot,shift,A,B,flg,ts->jacP);
452:     PetscStackPop;
453:   } else {
454:     if (ts->ops->rhsjacobian) {
455:       PetscStackPush("TS user right-hand-side Jacobian");
456:       (*ts->ops->rhsjacobian)(ts,t,X,A,B,flg,ts->jacP);
457:       PetscStackPop;
458:     } else {
459:       MatAssemblyBegin(*A,MAT_FINAL_ASSEMBLY);
460:       MatAssemblyEnd(*A,MAT_FINAL_ASSEMBLY);
461:       if (*A != *B) {
462:         MatAssemblyBegin(*B,MAT_FINAL_ASSEMBLY);
463:         MatAssemblyEnd(*B,MAT_FINAL_ASSEMBLY);
464:       }
465:     }

467:     /* Convert to implicit form */
468:     /* inefficient because these operations will normally traverse all matrix elements twice */
469:     MatScale(*A,-1);
470:     if (ts->Alhs) {
471:       MatAXPY(*A,shift,ts->Alhs,DIFFERENT_NONZERO_PATTERN);
472:     } else {
473:       MatShift(*A,shift);
474:     }
475:     if (*A != *B) {
476:       MatScale(*B,-1);
477:       MatShift(*B,shift);
478:     }
479:   }
480:   PetscLogEventEnd(TS_JacobianEval,ts,X,*A,*B);
481:   return(0);
482: }

486: /*@C
487:     TSSetRHSFunction - Sets the routine for evaluating the function,
488:     F(t,u), where U_t = F(t,u).

490:     Collective on TS

492:     Input Parameters:
493: +   ts - the TS context obtained from TSCreate()
494: .   f - routine for evaluating the right-hand-side function
495: -   ctx - [optional] user-defined context for private data for the 
496:           function evaluation routine (may be PETSC_NULL)

498:     Calling sequence of func:
499: $     func (TS ts,PetscReal t,Vec u,Vec F,void *ctx);

501: +   t - current timestep
502: .   u - input vector
503: .   F - function vector
504: -   ctx - [optional] user-defined function context 

506:     Important: 
507:     The user MUST call either this routine or TSSetMatrices().

509:     Level: beginner

511: .keywords: TS, timestep, set, right-hand-side, function

513: .seealso: TSSetMatrices()
514: @*/
515: PetscErrorCode  TSSetRHSFunction(TS ts,PetscErrorCode (*f)(TS,PetscReal,Vec,Vec,void*),void *ctx)
516: {

520:   if (ts->problem_type == TS_LINEAR) {
521:     SETERRQ(PETSC_ERR_ARG_WRONG,"Cannot set function for linear problem");
522:   }
523:   ts->ops->rhsfunction = f;
524:   ts->funP             = ctx;
525:   return(0);
526: }

530: /*@C
531:    TSSetMatrices - Sets the functions to compute the matrices Alhs and Arhs, 
532:    where Alhs(t) U_t = Arhs(t) U.

534:    Collective on TS

536:    Input Parameters:
537: +  ts   - the TS context obtained from TSCreate()
538: .  Arhs - matrix
539: .  frhs - the matrix evaluation routine for Arhs; use PETSC_NULL (PETSC_NULL_FUNCTION in fortran)
540:           if Arhs is not a function of t.
541: .  Alhs - matrix or PETSC_NULL if Alhs is an indentity matrix.
542: .  flhs - the matrix evaluation routine for Alhs; use PETSC_NULL (PETSC_NULL_FUNCTION in fortran)
543:           if Alhs is not a function of t.
544: .  flag - flag indicating information about the matrix structure of Arhs and Alhs. 
545:           The available options are
546:             SAME_NONZERO_PATTERN - Alhs has the same nonzero structure as Arhs
547:             DIFFERENT_NONZERO_PATTERN - Alhs has different nonzero structure as Arhs
548: -  ctx  - [optional] user-defined context for private data for the 
549:           matrix evaluation routine (may be PETSC_NULL)

551:    Calling sequence of func:
552: $     func(TS ts,PetscReal t,Mat *A,Mat *B,PetscInt *flag,void *ctx);

554: +  t - current timestep
555: .  A - matrix A, where U_t = A(t) U
556: .  B - preconditioner matrix, usually the same as A
557: .  flag - flag indicating information about the preconditioner matrix
558:           structure (same as flag in KSPSetOperators())
559: -  ctx - [optional] user-defined context for matrix evaluation routine

561:    Notes:  
562:    The routine func() takes Mat* as the matrix arguments rather than Mat.  
563:    This allows the matrix evaluation routine to replace Arhs or Alhs with a 
564:    completely new new matrix structure (not just different matrix elements)
565:    when appropriate, for instance, if the nonzero structure is changing
566:    throughout the global iterations.

568:    Important: 
569:    The user MUST call either this routine or TSSetRHSFunction().

571:    Level: beginner

573: .keywords: TS, timestep, set, matrix

575: .seealso: TSSetRHSFunction()
576: @*/
577: PetscErrorCode  TSSetMatrices(TS ts,Mat Arhs,PetscErrorCode (*frhs)(TS,PetscReal,Mat*,Mat*,MatStructure*,void*),Mat Alhs,PetscErrorCode (*flhs)(TS,PetscReal,Mat*,Mat*,MatStructure*,void*),MatStructure flag,void *ctx)
578: {
581:   if (Arhs){
584:     ts->Arhs           = Arhs;
585:     ts->ops->rhsmatrix = frhs;
586:   }
587:   if (Alhs){
590:     ts->Alhs           = Alhs;
591:     ts->ops->lhsmatrix = flhs;
592:   }
593: 
594:   ts->jacP           = ctx;
595:   ts->matflg         = flag;
596:   return(0);
597: }

601: /*@C
602:    TSGetMatrices - Returns the matrices Arhs and Alhs at the present timestep,
603:    where Alhs(t) U_t = Arhs(t) U.

605:    Not Collective, but parallel objects are returned if TS is parallel

607:    Input Parameter:
608: .  ts  - The TS context obtained from TSCreate()

610:    Output Parameters:
611: +  Arhs - The right-hand side matrix
612: .  Alhs - The left-hand side matrix
613: -  ctx - User-defined context for matrix evaluation routine

615:    Notes: You can pass in PETSC_NULL for any return argument you do not need.

617:    Level: intermediate

619: .seealso: TSSetMatrices(), TSGetTimeStep(), TSGetTime(), TSGetTimeStepNumber(), TSGetRHSJacobian()

621: .keywords: TS, timestep, get, matrix

623: @*/
624: PetscErrorCode  TSGetMatrices(TS ts,Mat *Arhs,Mat *Alhs,void **ctx)
625: {
628:   if (Arhs) *Arhs = ts->Arhs;
629:   if (Alhs) *Alhs = ts->Alhs;
630:   if (ctx)  *ctx = ts->jacP;
631:   return(0);
632: }

636: /*@C
637:    TSSetRHSJacobian - Sets the function to compute the Jacobian of F,
638:    where U_t = F(U,t), as well as the location to store the matrix.
639:    Use TSSetMatrices() for linear problems.

641:    Collective on TS

643:    Input Parameters:
644: +  ts  - the TS context obtained from TSCreate()
645: .  A   - Jacobian matrix
646: .  B   - preconditioner matrix (usually same as A)
647: .  f   - the Jacobian evaluation routine
648: -  ctx - [optional] user-defined context for private data for the 
649:          Jacobian evaluation routine (may be PETSC_NULL)

651:    Calling sequence of func:
652: $     func (TS ts,PetscReal t,Vec u,Mat *A,Mat *B,MatStructure *flag,void *ctx);

654: +  t - current timestep
655: .  u - input vector
656: .  A - matrix A, where U_t = A(t)u
657: .  B - preconditioner matrix, usually the same as A
658: .  flag - flag indicating information about the preconditioner matrix
659:           structure (same as flag in KSPSetOperators())
660: -  ctx - [optional] user-defined context for matrix evaluation routine

662:    Notes: 
663:    See KSPSetOperators() for important information about setting the flag
664:    output parameter in the routine func().  Be sure to read this information!

666:    The routine func() takes Mat * as the matrix arguments rather than Mat.  
667:    This allows the matrix evaluation routine to replace A and/or B with a 
668:    completely new matrix structure (not just different matrix elements)
669:    when appropriate, for instance, if the nonzero structure is changing
670:    throughout the global iterations.

672:    Level: beginner
673:    
674: .keywords: TS, timestep, set, right-hand-side, Jacobian

676: .seealso: TSDefaultComputeJacobianColor(),
677:           SNESDefaultComputeJacobianColor(), TSSetRHSFunction(), TSSetMatrices()

679: @*/
680: PetscErrorCode  TSSetRHSJacobian(TS ts,Mat A,Mat B,PetscErrorCode (*f)(TS,PetscReal,Vec,Mat*,Mat*,MatStructure*,void*),void *ctx)
681: {
688:   if (ts->problem_type != TS_NONLINEAR) {
689:     SETERRQ(PETSC_ERR_ARG_WRONG,"Not for linear problems; use TSSetMatrices()");
690:   }

692:   ts->ops->rhsjacobian = f;
693:   ts->jacP             = ctx;
694:   ts->Arhs             = A;
695:   ts->B                = B;
696:   return(0);
697: }


702: /*@C
703:    TSSetIFunction - Set the function to compute F(t,U,U_t) where F = 0 is the DAE to be solved.

705:    Collective on TS

707:    Input Parameters:
708: +  ts  - the TS context obtained from TSCreate()
709: .  f   - the function evaluation routine
710: -  ctx - user-defined context for private data for the function evaluation routine (may be PETSC_NULL)

712:    Calling sequence of f:
713: $  f(TS ts,PetscReal t,Vec u,Vec u_t,Vec F,ctx);

715: +  t   - time at step/stage being solved
716: .  u   - state vector
717: .  u_t - time derivative of state vector
718: .  F   - function vector
719: -  ctx - [optional] user-defined context for matrix evaluation routine

721:    Important:
722:    The user MUST call either this routine, TSSetRHSFunction(), or TSSetMatrices().  This routine must be used when not solving an ODE.

724:    Level: beginner

726: .keywords: TS, timestep, set, DAE, Jacobian

728: .seealso: TSSetMatrices(), TSSetRHSFunction(), TSSetIJacobian()
729: @*/
730: PetscErrorCode  TSSetIFunction(TS ts,TSIFunction f,void *ctx)
731: {

735:   ts->ops->ifunction = f;
736:   ts->funP           = ctx;
737:   return(0);
738: }

742: /*@C
743:    TSSetIJacobian - Set the function to compute the Jacobian of
744:    G(U) = F(t,U,U0+a*U) where F(t,U,U_t) = 0 is the DAE to be solved.

746:    Collective on TS

748:    Input Parameters:
749: +  ts  - the TS context obtained from TSCreate()
750: .  A   - Jacobian matrix
751: .  B   - preconditioning matrix for A (may be same as A)
752: .  f   - the Jacobian evaluation routine
753: -  ctx - user-defined context for private data for the Jacobian evaluation routine (may be PETSC_NULL)

755:    Calling sequence of f:
756: $  f(TS ts,PetscReal t,Vec u,Vec u_t,PetscReal a,Mat *A,Mat *B,MatStructure *flag,void *ctx);

758: +  t    - time at step/stage being solved
759: .  u    - state vector
760: .  u_t  - time derivative of state vector
761: .  a    - shift
762: .  A    - Jacobian of G(U) = F(t,U,U0+a*U), equivalent to dF/dU + a*dF/dU_t
763: .  B    - preconditioning matrix for A, may be same as A
764: .  flag - flag indicating information about the preconditioner matrix
765:           structure (same as flag in KSPSetOperators())
766: -  ctx  - [optional] user-defined context for matrix evaluation routine

768:    Notes:
769:    The matrices A and B are exactly the matrices that are used by SNES for the nonlinear solve.

771:    Level: beginner

773: .keywords: TS, timestep, DAE, Jacobian

775: .seealso: TSSetIFunction(), TSSetRHSJacobian()

777: @*/
778: PetscErrorCode  TSSetIJacobian(TS ts,Mat A,Mat B,TSIJacobian f,void *ctx)
779: {

788:   if (f)   ts->ops->ijacobian = f;
789:   if (ctx) ts->jacP             = ctx;
790:   if (A) {
791:     PetscObjectReference((PetscObject)A);
792:     if (ts->A) {MatDestroy(ts->A);}
793:     ts->A = A;
794:   }
795: #if 0
796:   /* The sane and consistent alternative */
797:   if (B) {
798:     PetscObjectReference((PetscObject)B);
799:     if (ts->B) {MatDestroy(ts->B);}
800:     ts->B = B;
801:   }
802: #else
803:   /* Don't reference B because TSDestroy() doesn't destroy it.  These ownership semantics are awkward and inconsistent. */
804:   if (B) ts->B = B;
805: #endif
806:   return(0);
807: }

811: /*@C
812:     TSView - Prints the TS data structure.

814:     Collective on TS

816:     Input Parameters:
817: +   ts - the TS context obtained from TSCreate()
818: -   viewer - visualization context

820:     Options Database Key:
821: .   -ts_view - calls TSView() at end of TSStep()

823:     Notes:
824:     The available visualization contexts include
825: +     PETSC_VIEWER_STDOUT_SELF - standard output (default)
826: -     PETSC_VIEWER_STDOUT_WORLD - synchronized standard
827:          output where only the first processor opens
828:          the file.  All other processors send their 
829:          data to the first processor to print. 

831:     The user can open an alternative visualization context with
832:     PetscViewerASCIIOpen() - output to a specified file.

834:     Level: beginner

836: .keywords: TS, timestep, view

838: .seealso: PetscViewerASCIIOpen()
839: @*/
840: PetscErrorCode  TSView(TS ts,PetscViewer viewer)
841: {
843:   const TSType   type;
844:   PetscTruth     iascii,isstring;

848:   if (!viewer) {
849:     PetscViewerASCIIGetStdout(((PetscObject)ts)->comm,&viewer);
850:   }

854:   PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&iascii);
855:   PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_STRING,&isstring);
856:   if (iascii) {
857:     PetscViewerASCIIPrintf(viewer,"TS Object:\n");
858:     TSGetType(ts,&type);
859:     if (type) {
860:       PetscViewerASCIIPrintf(viewer,"  type: %s\n",type);
861:     } else {
862:       PetscViewerASCIIPrintf(viewer,"  type: not yet set\n");
863:     }
864:     if (ts->ops->view) {
865:       PetscViewerASCIIPushTab(viewer);
866:       (*ts->ops->view)(ts,viewer);
867:       PetscViewerASCIIPopTab(viewer);
868:     }
869:     PetscViewerASCIIPrintf(viewer,"  maximum steps=%D\n",ts->max_steps);
870:     PetscViewerASCIIPrintf(viewer,"  maximum time=%G\n",ts->max_time);
871:     if (ts->problem_type == TS_NONLINEAR) {
872:       PetscViewerASCIIPrintf(viewer,"  total number of nonlinear solver iterations=%D\n",ts->nonlinear_its);
873:     }
874:     PetscViewerASCIIPrintf(viewer,"  total number of linear solver iterations=%D\n",ts->linear_its);
875:   } else if (isstring) {
876:     TSGetType(ts,&type);
877:     PetscViewerStringSPrintf(viewer," %-7.7s",type);
878:   }
879:   PetscViewerASCIIPushTab(viewer);
880:   if (ts->ksp) {KSPView(ts->ksp,viewer);}
881:   if (ts->snes) {SNESView(ts->snes,viewer);}
882:   PetscViewerASCIIPopTab(viewer);
883:   return(0);
884: }


889: /*@C
890:    TSSetApplicationContext - Sets an optional user-defined context for 
891:    the timesteppers.

893:    Collective on TS

895:    Input Parameters:
896: +  ts - the TS context obtained from TSCreate()
897: -  usrP - optional user context

899:    Level: intermediate

901: .keywords: TS, timestep, set, application, context

903: .seealso: TSGetApplicationContext()
904: @*/
905: PetscErrorCode  TSSetApplicationContext(TS ts,void *usrP)
906: {
909:   ts->user = usrP;
910:   return(0);
911: }

915: /*@C
916:     TSGetApplicationContext - Gets the user-defined context for the 
917:     timestepper.

919:     Not Collective

921:     Input Parameter:
922: .   ts - the TS context obtained from TSCreate()

924:     Output Parameter:
925: .   usrP - user context

927:     Level: intermediate

929: .keywords: TS, timestep, get, application, context

931: .seealso: TSSetApplicationContext()
932: @*/
933: PetscErrorCode  TSGetApplicationContext(TS ts,void **usrP)
934: {
937:   *usrP = ts->user;
938:   return(0);
939: }

943: /*@
944:    TSGetTimeStepNumber - Gets the current number of timesteps.

946:    Not Collective

948:    Input Parameter:
949: .  ts - the TS context obtained from TSCreate()

951:    Output Parameter:
952: .  iter - number steps so far

954:    Level: intermediate

956: .keywords: TS, timestep, get, iteration, number
957: @*/
958: PetscErrorCode  TSGetTimeStepNumber(TS ts,PetscInt* iter)
959: {
963:   *iter = ts->steps;
964:   return(0);
965: }

969: /*@
970:    TSSetInitialTimeStep - Sets the initial timestep to be used, 
971:    as well as the initial time.

973:    Collective on TS

975:    Input Parameters:
976: +  ts - the TS context obtained from TSCreate()
977: .  initial_time - the initial time
978: -  time_step - the size of the timestep

980:    Level: intermediate

982: .seealso: TSSetTimeStep(), TSGetTimeStep()

984: .keywords: TS, set, initial, timestep
985: @*/
986: PetscErrorCode  TSSetInitialTimeStep(TS ts,PetscReal initial_time,PetscReal time_step)
987: {
990:   ts->time_step         = time_step;
991:   ts->initial_time_step = time_step;
992:   ts->ptime             = initial_time;
993:   return(0);
994: }

998: /*@
999:    TSSetTimeStep - Allows one to reset the timestep at any time,
1000:    useful for simple pseudo-timestepping codes.

1002:    Collective on TS

1004:    Input Parameters:
1005: +  ts - the TS context obtained from TSCreate()
1006: -  time_step - the size of the timestep

1008:    Level: intermediate

1010: .seealso: TSSetInitialTimeStep(), TSGetTimeStep()

1012: .keywords: TS, set, timestep
1013: @*/
1014: PetscErrorCode  TSSetTimeStep(TS ts,PetscReal time_step)
1015: {
1018:   ts->time_step = time_step;
1019:   return(0);
1020: }

1024: /*@
1025:    TSGetTimeStep - Gets the current timestep size.

1027:    Not Collective

1029:    Input Parameter:
1030: .  ts - the TS context obtained from TSCreate()

1032:    Output Parameter:
1033: .  dt - the current timestep size

1035:    Level: intermediate

1037: .seealso: TSSetInitialTimeStep(), TSGetTimeStep()

1039: .keywords: TS, get, timestep
1040: @*/
1041: PetscErrorCode  TSGetTimeStep(TS ts,PetscReal* dt)
1042: {
1046:   *dt = ts->time_step;
1047:   return(0);
1048: }

1052: /*@
1053:    TSGetSolution - Returns the solution at the present timestep. It
1054:    is valid to call this routine inside the function that you are evaluating
1055:    in order to move to the new timestep. This vector not changed until
1056:    the solution at the next timestep has been calculated.

1058:    Not Collective, but Vec returned is parallel if TS is parallel

1060:    Input Parameter:
1061: .  ts - the TS context obtained from TSCreate()

1063:    Output Parameter:
1064: .  v - the vector containing the solution

1066:    Level: intermediate

1068: .seealso: TSGetTimeStep()

1070: .keywords: TS, timestep, get, solution
1071: @*/
1072: PetscErrorCode  TSGetSolution(TS ts,Vec *v)
1073: {
1077:   *v = ts->vec_sol_always;
1078:   return(0);
1079: }

1081: /* ----- Routines to initialize and destroy a timestepper ---- */
1084: /*@
1085:   TSSetProblemType - Sets the type of problem to be solved.

1087:   Not collective

1089:   Input Parameters:
1090: + ts   - The TS
1091: - type - One of TS_LINEAR, TS_NONLINEAR where these types refer to problems of the forms
1092: .vb
1093:          U_t = A U    
1094:          U_t = A(t) U 
1095:          U_t = F(t,U) 
1096: .ve

1098:    Level: beginner

1100: .keywords: TS, problem type
1101: .seealso: TSSetUp(), TSProblemType, TS
1102: @*/
1103: PetscErrorCode  TSSetProblemType(TS ts, TSProblemType type)
1104: {
1107:   ts->problem_type = type;
1108:   return(0);
1109: }

1113: /*@C
1114:   TSGetProblemType - Gets the type of problem to be solved.

1116:   Not collective

1118:   Input Parameter:
1119: . ts   - The TS

1121:   Output Parameter:
1122: . type - One of TS_LINEAR, TS_NONLINEAR where these types refer to problems of the forms
1123: .vb
1124:          U_t = A U    
1125:          U_t = A(t) U 
1126:          U_t = F(t,U) 
1127: .ve

1129:    Level: beginner

1131: .keywords: TS, problem type
1132: .seealso: TSSetUp(), TSProblemType, TS
1133: @*/
1134: PetscErrorCode  TSGetProblemType(TS ts, TSProblemType *type)
1135: {
1139:   *type = ts->problem_type;
1140:   return(0);
1141: }

1145: /*@
1146:    TSSetUp - Sets up the internal data structures for the later use
1147:    of a timestepper.  

1149:    Collective on TS

1151:    Input Parameter:
1152: .  ts - the TS context obtained from TSCreate()

1154:    Notes:
1155:    For basic use of the TS solvers the user need not explicitly call
1156:    TSSetUp(), since these actions will automatically occur during
1157:    the call to TSStep().  However, if one wishes to control this
1158:    phase separately, TSSetUp() should be called after TSCreate()
1159:    and optional routines of the form TSSetXXX(), but before TSStep().  

1161:    Level: advanced

1163: .keywords: TS, timestep, setup

1165: .seealso: TSCreate(), TSStep(), TSDestroy()
1166: @*/
1167: PetscErrorCode  TSSetUp(TS ts)
1168: {

1173:   if (!ts->vec_sol) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Must call TSSetSolution() first");
1174:   if (!((PetscObject)ts)->type_name) {
1175:     TSSetType(ts,TSEULER);
1176:   }
1177:   (*ts->ops->setup)(ts);
1178:   ts->setupcalled = 1;
1179:   return(0);
1180: }

1184: /*@
1185:    TSDestroy - Destroys the timestepper context that was created
1186:    with TSCreate().

1188:    Collective on TS

1190:    Input Parameter:
1191: .  ts - the TS context obtained from TSCreate()

1193:    Level: beginner

1195: .keywords: TS, timestepper, destroy

1197: .seealso: TSCreate(), TSSetUp(), TSSolve()
1198: @*/
1199: PetscErrorCode  TSDestroy(TS ts)
1200: {

1205:   if (--((PetscObject)ts)->refct > 0) return(0);

1207:   /* if memory was published with AMS then destroy it */
1208:   PetscObjectDepublish(ts);
1209:   if (ts->A) {MatDestroy(ts->A);CHKERRQ(ierr)}
1210:   if (ts->ksp) {KSPDestroy(ts->ksp);}
1211:   if (ts->snes) {SNESDestroy(ts->snes);}
1212:   if (ts->ops->destroy) {(*(ts)->ops->destroy)(ts);}
1213:   TSMonitorCancel(ts);
1214:   PetscHeaderDestroy(ts);
1215:   return(0);
1216: }

1220: /*@
1221:    TSGetSNES - Returns the SNES (nonlinear solver) associated with 
1222:    a TS (timestepper) context. Valid only for nonlinear problems.

1224:    Not Collective, but SNES is parallel if TS is parallel

1226:    Input Parameter:
1227: .  ts - the TS context obtained from TSCreate()

1229:    Output Parameter:
1230: .  snes - the nonlinear solver context

1232:    Notes:
1233:    The user can then directly manipulate the SNES context to set various
1234:    options, etc.  Likewise, the user can then extract and manipulate the 
1235:    KSP, KSP, and PC contexts as well.

1237:    TSGetSNES() does not work for integrators that do not use SNES; in
1238:    this case TSGetSNES() returns PETSC_NULL in snes.

1240:    Level: beginner

1242: .keywords: timestep, get, SNES
1243: @*/
1244: PetscErrorCode  TSGetSNES(TS ts,SNES *snes)
1245: {
1249:   if (((PetscObject)ts)->type_name == PETSC_NULL)
1250:     SETERRQ(PETSC_ERR_ARG_NULL,"SNES is not created yet. Call TSSetType() first");
1251:   if (ts->problem_type == TS_LINEAR) SETERRQ(PETSC_ERR_ARG_WRONG,"Nonlinear only; use TSGetKSP()");
1252:   *snes = ts->snes;
1253:   return(0);
1254: }

1258: /*@
1259:    TSGetKSP - Returns the KSP (linear solver) associated with 
1260:    a TS (timestepper) context.

1262:    Not Collective, but KSP is parallel if TS is parallel

1264:    Input Parameter:
1265: .  ts - the TS context obtained from TSCreate()

1267:    Output Parameter:
1268: .  ksp - the nonlinear solver context

1270:    Notes:
1271:    The user can then directly manipulate the KSP context to set various
1272:    options, etc.  Likewise, the user can then extract and manipulate the 
1273:    KSP and PC contexts as well.

1275:    TSGetKSP() does not work for integrators that do not use KSP;
1276:    in this case TSGetKSP() returns PETSC_NULL in ksp.

1278:    Level: beginner

1280: .keywords: timestep, get, KSP
1281: @*/
1282: PetscErrorCode  TSGetKSP(TS ts,KSP *ksp)
1283: {
1287:   if (((PetscObject)ts)->type_name == PETSC_NULL)
1288:     SETERRQ(PETSC_ERR_ARG_NULL,"KSP is not created yet. Call TSSetType() first");
1289:   if (ts->problem_type != TS_LINEAR) SETERRQ(PETSC_ERR_ARG_WRONG,"Linear only; use TSGetSNES()");
1290:   *ksp = ts->ksp;
1291:   return(0);
1292: }

1294: /* ----------- Routines to set solver parameters ---------- */

1298: /*@
1299:    TSGetDuration - Gets the maximum number of timesteps to use and 
1300:    maximum time for iteration.

1302:    Collective on TS

1304:    Input Parameters:
1305: +  ts       - the TS context obtained from TSCreate()
1306: .  maxsteps - maximum number of iterations to use, or PETSC_NULL
1307: -  maxtime  - final time to iterate to, or PETSC_NULL

1309:    Level: intermediate

1311: .keywords: TS, timestep, get, maximum, iterations, time
1312: @*/
1313: PetscErrorCode  TSGetDuration(TS ts, PetscInt *maxsteps, PetscReal *maxtime)
1314: {
1317:   if (maxsteps) {
1319:     *maxsteps = ts->max_steps;
1320:   }
1321:   if (maxtime ) {
1323:     *maxtime  = ts->max_time;
1324:   }
1325:   return(0);
1326: }

1330: /*@
1331:    TSSetDuration - Sets the maximum number of timesteps to use and 
1332:    maximum time for iteration.

1334:    Collective on TS

1336:    Input Parameters:
1337: +  ts - the TS context obtained from TSCreate()
1338: .  maxsteps - maximum number of iterations to use
1339: -  maxtime - final time to iterate to

1341:    Options Database Keys:
1342: .  -ts_max_steps <maxsteps> - Sets maxsteps
1343: .  -ts_max_time <maxtime> - Sets maxtime

1345:    Notes:
1346:    The default maximum number of iterations is 5000. Default time is 5.0

1348:    Level: intermediate

1350: .keywords: TS, timestep, set, maximum, iterations
1351: @*/
1352: PetscErrorCode  TSSetDuration(TS ts,PetscInt maxsteps,PetscReal maxtime)
1353: {
1356:   ts->max_steps = maxsteps;
1357:   ts->max_time  = maxtime;
1358:   return(0);
1359: }

1363: /*@
1364:    TSSetSolution - Sets the initial solution vector
1365:    for use by the TS routines.

1367:    Collective on TS and Vec

1369:    Input Parameters:
1370: +  ts - the TS context obtained from TSCreate()
1371: -  x - the solution vector

1373:    Level: beginner

1375: .keywords: TS, timestep, set, solution, initial conditions
1376: @*/
1377: PetscErrorCode  TSSetSolution(TS ts,Vec x)
1378: {
1382:   ts->vec_sol        = ts->vec_sol_always = x;
1383:   return(0);
1384: }

1388: /*@C
1389:   TSSetPreStep - Sets the general-purpose function
1390:   called once at the beginning of each time step.

1392:   Collective on TS

1394:   Input Parameters:
1395: + ts   - The TS context obtained from TSCreate()
1396: - func - The function

1398:   Calling sequence of func:
1399: . func (TS ts);

1401:   Level: intermediate

1403: .keywords: TS, timestep
1404: @*/
1405: PetscErrorCode  TSSetPreStep(TS ts, PetscErrorCode (*func)(TS))
1406: {
1409:   ts->ops->prestep = func;
1410:   return(0);
1411: }

1415: /*@C
1416:   TSPreStep - Runs the user-defined pre-step function.

1418:   Collective on TS

1420:   Input Parameters:
1421: . ts   - The TS context obtained from TSCreate()

1423:   Notes:
1424:   TSPreStep() is typically used within time stepping implementations,
1425:   so most users would not generally call this routine themselves.

1427:   Level: developer

1429: .keywords: TS, timestep
1430: @*/
1431: PetscErrorCode  TSPreStep(TS ts)
1432: {

1437:   if (ts->ops->prestep) {
1438:     PetscStackPush("TS PreStep function");
1439:     CHKMEMQ;
1440:     (*ts->ops->prestep)(ts);
1441:     CHKMEMQ;
1442:     PetscStackPop;
1443:   }
1444:   return(0);
1445: }

1449: /*@
1450:   TSDefaultPreStep - The default pre-stepping function which does nothing.

1452:   Collective on TS

1454:   Input Parameters:
1455: . ts  - The TS context obtained from TSCreate()

1457:   Level: developer

1459: .keywords: TS, timestep
1460: @*/
1461: PetscErrorCode  TSDefaultPreStep(TS ts)
1462: {
1464:   return(0);
1465: }

1469: /*@C
1470:   TSSetPostStep - Sets the general-purpose function
1471:   called once at the end of each time step.

1473:   Collective on TS

1475:   Input Parameters:
1476: + ts   - The TS context obtained from TSCreate()
1477: - func - The function

1479:   Calling sequence of func:
1480: . func (TS ts);

1482:   Level: intermediate

1484: .keywords: TS, timestep
1485: @*/
1486: PetscErrorCode  TSSetPostStep(TS ts, PetscErrorCode (*func)(TS))
1487: {
1490:   ts->ops->poststep = func;
1491:   return(0);
1492: }

1496: /*@C
1497:   TSPostStep - Runs the user-defined post-step function.

1499:   Collective on TS

1501:   Input Parameters:
1502: . ts   - The TS context obtained from TSCreate()

1504:   Notes:
1505:   TSPostStep() is typically used within time stepping implementations,
1506:   so most users would not generally call this routine themselves.

1508:   Level: developer

1510: .keywords: TS, timestep
1511: @*/
1512: PetscErrorCode  TSPostStep(TS ts)
1513: {

1518:   if (ts->ops->poststep) {
1519:     PetscStackPush("TS PostStep function");
1520:     CHKMEMQ;
1521:     (*ts->ops->poststep)(ts);
1522:     CHKMEMQ;
1523:     PetscStackPop;
1524:   }
1525:   return(0);
1526: }

1530: /*@
1531:   TSDefaultPostStep - The default post-stepping function which does nothing.

1533:   Collective on TS

1535:   Input Parameters:
1536: . ts  - The TS context obtained from TSCreate()

1538:   Level: developer

1540: .keywords: TS, timestep
1541: @*/
1542: PetscErrorCode  TSDefaultPostStep(TS ts)
1543: {
1545:   return(0);
1546: }

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

1552: /*@C
1553:    TSMonitorSet - Sets an ADDITIONAL function that is to be used at every
1554:    timestep to display the iteration's  progress.   

1556:    Collective on TS

1558:    Input Parameters:
1559: +  ts - the TS context obtained from TSCreate()
1560: .  func - monitoring routine
1561: .  mctx - [optional] user-defined context for private data for the 
1562:              monitor routine (use PETSC_NULL if no context is desired)
1563: -  monitordestroy - [optional] routine that frees monitor context
1564:           (may be PETSC_NULL)

1566:    Calling sequence of func:
1567: $    int func(TS ts,PetscInt steps,PetscReal time,Vec x,void *mctx)

1569: +    ts - the TS context
1570: .    steps - iteration number
1571: .    time - current time
1572: .    x - current iterate
1573: -    mctx - [optional] monitoring context

1575:    Notes:
1576:    This routine adds an additional monitor to the list of monitors that 
1577:    already has been loaded.

1579:    Fortran notes: Only a single monitor function can be set for each TS object

1581:    Level: intermediate

1583: .keywords: TS, timestep, set, monitor

1585: .seealso: TSMonitorDefault(), TSMonitorCancel()
1586: @*/
1587: PetscErrorCode  TSMonitorSet(TS ts,PetscErrorCode (*monitor)(TS,PetscInt,PetscReal,Vec,void*),void *mctx,PetscErrorCode (*mdestroy)(void*))
1588: {
1591:   if (ts->numbermonitors >= MAXTSMONITORS) {
1592:     SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Too many monitors set");
1593:   }
1594:   ts->monitor[ts->numbermonitors]           = monitor;
1595:   ts->mdestroy[ts->numbermonitors]          = mdestroy;
1596:   ts->monitorcontext[ts->numbermonitors++]  = (void*)mctx;
1597:   return(0);
1598: }

1602: /*@C
1603:    TSMonitorCancel - Clears all the monitors that have been set on a time-step object.   

1605:    Collective on TS

1607:    Input Parameters:
1608: .  ts - the TS context obtained from TSCreate()

1610:    Notes:
1611:    There is no way to remove a single, specific monitor.

1613:    Level: intermediate

1615: .keywords: TS, timestep, set, monitor

1617: .seealso: TSMonitorDefault(), TSMonitorSet()
1618: @*/
1619: PetscErrorCode  TSMonitorCancel(TS ts)
1620: {
1622:   PetscInt       i;

1626:   for (i=0; i<ts->numbermonitors; i++) {
1627:     if (ts->mdestroy[i]) {
1628:       (*ts->mdestroy[i])(ts->monitorcontext[i]);
1629:     }
1630:   }
1631:   ts->numbermonitors = 0;
1632:   return(0);
1633: }

1637: /*@
1638:    TSMonitorDefault - Sets the Default monitor

1640:    Level: intermediate

1642: .keywords: TS, set, monitor

1644: .seealso: TSMonitorDefault(), TSMonitorSet()
1645: @*/
1646: PetscErrorCode TSMonitorDefault(TS ts,PetscInt step,PetscReal ptime,Vec v,void *ctx)
1647: {
1648:   PetscErrorCode          ierr;
1649:   PetscViewerASCIIMonitor viewer = (PetscViewerASCIIMonitor)ctx;

1652:   if (!ctx) {
1653:     PetscViewerASCIIMonitorCreate(((PetscObject)ts)->comm,"stdout",0,&viewer);
1654:   }
1655:   PetscViewerASCIIMonitorPrintf(viewer,"timestep %D dt %G time %G\n",step,ts->time_step,ptime);
1656:   if (!ctx) {
1657:     PetscViewerASCIIMonitorDestroy(viewer);
1658:   }
1659:   return(0);
1660: }

1664: /*@
1665:    TSStep - Steps the requested number of timesteps.

1667:    Collective on TS

1669:    Input Parameter:
1670: .  ts - the TS context obtained from TSCreate()

1672:    Output Parameters:
1673: +  steps - number of iterations until termination
1674: -  ptime - time until termination

1676:    Level: beginner

1678: .keywords: TS, timestep, solve

1680: .seealso: TSCreate(), TSSetUp(), TSDestroy()
1681: @*/
1682: PetscErrorCode  TSStep(TS ts,PetscInt *steps,PetscReal *ptime)
1683: {

1688:   if (!ts->setupcalled) {
1689:     TSSetUp(ts);
1690:   }

1692:   PetscLogEventBegin(TS_Step, ts, 0, 0, 0);
1693:   (*ts->ops->step)(ts, steps, ptime);
1694:   PetscLogEventEnd(TS_Step, ts, 0, 0, 0);

1696:   if (!PetscPreLoadingOn) {
1697:     TSViewFromOptions(ts,((PetscObject)ts)->name);
1698:   }
1699:   return(0);
1700: }

1704: /*@
1705:    TSSolve - Steps the requested number of timesteps.

1707:    Collective on TS

1709:    Input Parameter:
1710: +  ts - the TS context obtained from TSCreate()
1711: -  x - the solution vector, or PETSC_NULL if it was set with TSSetSolution()

1713:    Level: beginner

1715: .keywords: TS, timestep, solve

1717: .seealso: TSCreate(), TSSetSolution(), TSStep()
1718: @*/
1719: PetscErrorCode  TSSolve(TS ts, Vec x)
1720: {
1721:   PetscInt       steps;
1722:   PetscReal      ptime;
1726:   /* set solution vector if provided */
1727:   if (x) { TSSetSolution(ts, x);  }
1728:   /* reset time step and iteration counters */
1729:   ts->steps = 0; ts->linear_its = 0; ts->nonlinear_its = 0;
1730:   /* steps the requested number of timesteps. */
1731:   TSStep(ts, &steps, &ptime);
1732:   return(0);
1733: }

1737: /*
1738:      Runs the user provided monitor routines, if they exists.
1739: */
1740: PetscErrorCode TSMonitor(TS ts,PetscInt step,PetscReal ptime,Vec x)
1741: {
1743:   PetscInt i,n = ts->numbermonitors;

1746:   for (i=0; i<n; i++) {
1747:     (*ts->monitor[i])(ts,step,ptime,x,ts->monitorcontext[i]);
1748:   }
1749:   return(0);
1750: }

1752: /* ------------------------------------------------------------------------*/

1756: /*@C
1757:    TSMonitorLGCreate - Creates a line graph context for use with 
1758:    TS to monitor convergence of preconditioned residual norms.

1760:    Collective on TS

1762:    Input Parameters:
1763: +  host - the X display to open, or null for the local machine
1764: .  label - the title to put in the title bar
1765: .  x, y - the screen coordinates of the upper left coordinate of the window
1766: -  m, n - the screen width and height in pixels

1768:    Output Parameter:
1769: .  draw - the drawing context

1771:    Options Database Key:
1772: .  -ts_monitor_draw - automatically sets line graph monitor

1774:    Notes: 
1775:    Use TSMonitorLGDestroy() to destroy this line graph, not PetscDrawLGDestroy().

1777:    Level: intermediate

1779: .keywords: TS, monitor, line graph, residual, seealso

1781: .seealso: TSMonitorLGDestroy(), TSMonitorSet()

1783: @*/
1784: PetscErrorCode  TSMonitorLGCreate(const char host[],const char label[],int x,int y,int m,int n,PetscDrawLG *draw)
1785: {
1786:   PetscDraw      win;

1790:   PetscDrawCreate(PETSC_COMM_SELF,host,label,x,y,m,n,&win);
1791:   PetscDrawSetType(win,PETSC_DRAW_X);
1792:   PetscDrawLGCreate(win,1,draw);
1793:   PetscDrawLGIndicateDataPoints(*draw);

1795:   PetscLogObjectParent(*draw,win);
1796:   return(0);
1797: }

1801: PetscErrorCode TSMonitorLG(TS ts,PetscInt n,PetscReal ptime,Vec v,void *monctx)
1802: {
1803:   PetscDrawLG    lg = (PetscDrawLG) monctx;
1804:   PetscReal      x,y = ptime;

1808:   if (!monctx) {
1809:     MPI_Comm    comm;
1810:     PetscViewer viewer;

1812:     PetscObjectGetComm((PetscObject)ts,&comm);
1813:     viewer = PETSC_VIEWER_DRAW_(comm);
1814:     PetscViewerDrawGetDrawLG(viewer,0,&lg);
1815:   }

1817:   if (!n) {PetscDrawLGReset(lg);}
1818:   x = (PetscReal)n;
1819:   PetscDrawLGAddPoint(lg,&x,&y);
1820:   if (n < 20 || (n % 5)) {
1821:     PetscDrawLGDraw(lg);
1822:   }
1823:   return(0);
1824: }

1828: /*@C
1829:    TSMonitorLGDestroy - Destroys a line graph context that was created 
1830:    with TSMonitorLGCreate().

1832:    Collective on PetscDrawLG

1834:    Input Parameter:
1835: .  draw - the drawing context

1837:    Level: intermediate

1839: .keywords: TS, monitor, line graph, destroy

1841: .seealso: TSMonitorLGCreate(),  TSMonitorSet(), TSMonitorLG();
1842: @*/
1843: PetscErrorCode  TSMonitorLGDestroy(PetscDrawLG drawlg)
1844: {
1845:   PetscDraw      draw;

1849:   PetscDrawLGGetDraw(drawlg,&draw);
1850:   PetscDrawDestroy(draw);
1851:   PetscDrawLGDestroy(drawlg);
1852:   return(0);
1853: }

1857: /*@
1858:    TSGetTime - Gets the current time.

1860:    Not Collective

1862:    Input Parameter:
1863: .  ts - the TS context obtained from TSCreate()

1865:    Output Parameter:
1866: .  t  - the current time

1868:    Level: beginner

1870: .seealso: TSSetInitialTimeStep(), TSGetTimeStep()

1872: .keywords: TS, get, time
1873: @*/
1874: PetscErrorCode  TSGetTime(TS ts,PetscReal* t)
1875: {
1879:   *t = ts->ptime;
1880:   return(0);
1881: }

1885: /*@
1886:    TSSetTime - Allows one to reset the time.

1888:    Collective on TS

1890:    Input Parameters:
1891: +  ts - the TS context obtained from TSCreate()
1892: -  time - the time

1894:    Level: intermediate

1896: .seealso: TSGetTime(), TSSetDuration()

1898: .keywords: TS, set, time
1899: @*/
1900: PetscErrorCode  TSSetTime(TS ts, PetscReal t)
1901: {
1904:   ts->ptime = t;
1905:   return(0);
1906: }

1910: /*@C
1911:    TSSetOptionsPrefix - Sets the prefix used for searching for all
1912:    TS options in the database.

1914:    Collective on TS

1916:    Input Parameter:
1917: +  ts     - The TS context
1918: -  prefix - The prefix to prepend to all option names

1920:    Notes:
1921:    A hyphen (-) must NOT be given at the beginning of the prefix name.
1922:    The first character of all runtime options is AUTOMATICALLY the
1923:    hyphen.

1925:    Level: advanced

1927: .keywords: TS, set, options, prefix, database

1929: .seealso: TSSetFromOptions()

1931: @*/
1932: PetscErrorCode  TSSetOptionsPrefix(TS ts,const char prefix[])
1933: {

1938:   PetscObjectSetOptionsPrefix((PetscObject)ts,prefix);
1939:   switch(ts->problem_type) {
1940:     case TS_NONLINEAR:
1941:       if (ts->snes) {
1942:         SNESSetOptionsPrefix(ts->snes,prefix);
1943:       }
1944:       break;
1945:     case TS_LINEAR:
1946:       if (ts->ksp) {
1947:         KSPSetOptionsPrefix(ts->ksp,prefix);
1948:       }
1949:       break;
1950:   }
1951:   return(0);
1952: }


1957: /*@C
1958:    TSAppendOptionsPrefix - Appends to the prefix used for searching for all
1959:    TS options in the database.

1961:    Collective on TS

1963:    Input Parameter:
1964: +  ts     - The TS context
1965: -  prefix - The prefix to prepend to all option names

1967:    Notes:
1968:    A hyphen (-) must NOT be given at the beginning of the prefix name.
1969:    The first character of all runtime options is AUTOMATICALLY the
1970:    hyphen.

1972:    Level: advanced

1974: .keywords: TS, append, options, prefix, database

1976: .seealso: TSGetOptionsPrefix()

1978: @*/
1979: PetscErrorCode  TSAppendOptionsPrefix(TS ts,const char prefix[])
1980: {

1985:   PetscObjectAppendOptionsPrefix((PetscObject)ts,prefix);
1986:   switch(ts->problem_type) {
1987:     case TS_NONLINEAR:
1988:       if (ts->snes) {
1989:         SNESAppendOptionsPrefix(ts->snes,prefix);
1990:       }
1991:       break;
1992:     case TS_LINEAR:
1993:       if (ts->ksp) {
1994:         KSPAppendOptionsPrefix(ts->ksp,prefix);
1995:       }
1996:       break;
1997:   }
1998:   return(0);
1999: }

2003: /*@C
2004:    TSGetOptionsPrefix - Sets the prefix used for searching for all
2005:    TS options in the database.

2007:    Not Collective

2009:    Input Parameter:
2010: .  ts - The TS context

2012:    Output Parameter:
2013: .  prefix - A pointer to the prefix string used

2015:    Notes: On the fortran side, the user should pass in a string 'prifix' of
2016:    sufficient length to hold the prefix.

2018:    Level: intermediate

2020: .keywords: TS, get, options, prefix, database

2022: .seealso: TSAppendOptionsPrefix()
2023: @*/
2024: PetscErrorCode  TSGetOptionsPrefix(TS ts,const char *prefix[])
2025: {

2031:   PetscObjectGetOptionsPrefix((PetscObject)ts,prefix);
2032:   return(0);
2033: }

2037: /*@C
2038:    TSGetRHSJacobian - Returns the Jacobian J at the present timestep.

2040:    Not Collective, but parallel objects are returned if TS is parallel

2042:    Input Parameter:
2043: .  ts  - The TS context obtained from TSCreate()

2045:    Output Parameters:
2046: +  J   - The Jacobian J of F, where U_t = F(U,t)
2047: .  M   - The preconditioner matrix, usually the same as J
2048: - ctx - User-defined context for Jacobian evaluation routine

2050:    Notes: You can pass in PETSC_NULL for any return argument you do not need.

2052:    Level: intermediate

2054: .seealso: TSGetTimeStep(), TSGetMatrices(), TSGetTime(), TSGetTimeStepNumber()

2056: .keywords: TS, timestep, get, matrix, Jacobian
2057: @*/
2058: PetscErrorCode  TSGetRHSJacobian(TS ts,Mat *J,Mat *M,void **ctx)
2059: {
2061:   if (J) *J = ts->Arhs;
2062:   if (M) *M = ts->B;
2063:   if (ctx) *ctx = ts->jacP;
2064:   return(0);
2065: }

2069: /*@C
2070:    TSGetIJacobian - Returns the implicit Jacobian at the present timestep.

2072:    Not Collective, but parallel objects are returned if TS is parallel

2074:    Input Parameter:
2075: .  ts  - The TS context obtained from TSCreate()

2077:    Output Parameters:
2078: +  A   - The Jacobian of F(t,U,U_t)
2079: .  B   - The preconditioner matrix, often the same as A
2080: .  f   - The function to compute the matrices
2081: - ctx - User-defined context for Jacobian evaluation routine

2083:    Notes: You can pass in PETSC_NULL for any return argument you do not need.

2085:    Level: advanced

2087: .seealso: TSGetTimeStep(), TSGetRHSJacobian(), TSGetMatrices(), TSGetTime(), TSGetTimeStepNumber()

2089: .keywords: TS, timestep, get, matrix, Jacobian
2090: @*/
2091: PetscErrorCode  TSGetIJacobian(TS ts,Mat *A,Mat *B,TSIJacobian *f,void **ctx)
2092: {
2094:   if (A) *A = ts->A;
2095:   if (B) *B = ts->B;
2096:   if (f) *f = ts->ops->ijacobian;
2097:   if (ctx) *ctx = ts->jacP;
2098:   return(0);
2099: }

2103: /*@C
2104:    TSMonitorSolution - Monitors progress of the TS solvers by calling 
2105:    VecView() for the solution at each timestep

2107:    Collective on TS

2109:    Input Parameters:
2110: +  ts - the TS context
2111: .  step - current time-step
2112: .  ptime - current time
2113: -  dummy - either a viewer or PETSC_NULL

2115:    Level: intermediate

2117: .keywords: TS,  vector, monitor, view

2119: .seealso: TSMonitorSet(), TSMonitorDefault(), VecView()
2120: @*/
2121: PetscErrorCode  TSMonitorSolution(TS ts,PetscInt step,PetscReal ptime,Vec x,void *dummy)
2122: {
2124:   PetscViewer    viewer = (PetscViewer) dummy;

2127:   if (!dummy) {
2128:     viewer = PETSC_VIEWER_DRAW_(((PetscObject)ts)->comm);
2129:   }
2130:   VecView(x,viewer);
2131:   return(0);
2132: }