xref: /petsc/src/ts/interface/ts.c (revision d2d6cebe7c034aec5d7d675a271af3ae6a2becaf)
1 #define PETSCTS_DLL
2 
3 #include "private/tsimpl.h"        /*I "petscts.h"  I*/
4 
5 /* Logging support */
6 PetscCookie PETSCTS_DLLEXPORT TS_COOKIE;
7 PetscLogEvent  TS_Step, TS_PseudoComputeTimeStep, TS_FunctionEval, TS_JacobianEval;
8 
9 #undef __FUNCT__
10 #define __FUNCT__ "TSSetTypeFromOptions"
11 /*
12   TSSetTypeFromOptions - Sets the type of ts from user options.
13 
14   Collective on TS
15 
16   Input Parameter:
17 . ts - The ts
18 
19   Level: intermediate
20 
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];
29   PetscErrorCode ierr;
30 
31   PetscFunctionBegin;
32   if (((PetscObject)ts)->type_name) {
33     defaultType = ((PetscObject)ts)->type_name;
34   } else {
35     defaultType = TSEULER;
36   }
37 
38   if (!TSRegisterAllCalled) {ierr = TSRegisterAll(PETSC_NULL);CHKERRQ(ierr);}
39   ierr = PetscOptionsList("-ts_type", "TS method"," TSSetType", TSList, defaultType, typeName, 256, &opt);CHKERRQ(ierr);
40   if (opt) {
41     ierr = TSSetType(ts, typeName);CHKERRQ(ierr);
42   } else {
43     ierr = TSSetType(ts, defaultType);CHKERRQ(ierr);
44   }
45   PetscFunctionReturn(0);
46 }
47 
48 #undef __FUNCT__
49 #define __FUNCT__ "TSSetFromOptions"
50 /*@
51    TSSetFromOptions - Sets various TS parameters from user options.
52 
53    Collective on TS
54 
55    Input Parameter:
56 .  ts - the TS context obtained from TSCreate()
57 
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
65 
66    Level: beginner
67 
68 .keywords: TS, timestep, set, options, database
69 
70 .seealso: TSGetType()
71 @*/
72 PetscErrorCode PETSCTS_DLLEXPORT TSSetFromOptions(TS ts)
73 {
74   PetscReal               dt;
75   PetscTruth              opt,flg;
76   PetscErrorCode          ierr;
77   PetscViewerASCIIMonitor monviewer;
78   char                    monfilename[PETSC_MAX_PATH_LEN];
79 
80   PetscFunctionBegin;
81   PetscValidHeaderSpecific(ts, TS_COOKIE,1);
82   ierr = PetscOptionsBegin(((PetscObject)ts)->comm, ((PetscObject)ts)->prefix, "Time step options", "TS");CHKERRQ(ierr);
83 
84     /* Handle generic TS options */
85     ierr = PetscOptionsInt("-ts_max_steps","Maximum number of time steps","TSSetDuration",ts->max_steps,&ts->max_steps,PETSC_NULL);CHKERRQ(ierr);
86     ierr = PetscOptionsReal("-ts_max_time","Time to run to","TSSetDuration",ts->max_time,&ts->max_time,PETSC_NULL);CHKERRQ(ierr);
87     ierr = PetscOptionsReal("-ts_init_time","Initial time","TSSetInitialTime", ts->ptime, &ts->ptime, PETSC_NULL);CHKERRQ(ierr);
88     ierr = PetscOptionsReal("-ts_dt","Initial time step","TSSetInitialTimeStep",ts->initial_time_step,&dt,&opt);CHKERRQ(ierr);
89     if (opt) {
90       ts->initial_time_step = ts->time_step = dt;
91     }
92 
93     /* Monitor options */
94     ierr = PetscOptionsString("-ts_monitor","Monitor timestep size","TSMonitorDefault","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr);
95     if (flg) {
96       ierr = PetscViewerASCIIMonitorCreate(((PetscObject)ts)->comm,monfilename,((PetscObject)ts)->tablevel,&monviewer);CHKERRQ(ierr);
97       ierr = TSMonitorSet(ts,TSMonitorDefault,monviewer,(PetscErrorCode (*)(void*))PetscViewerASCIIMonitorDestroy);CHKERRQ(ierr);
98     }
99     opt  = PETSC_FALSE;
100     ierr = PetscOptionsTruth("-ts_monitor_draw","Monitor timestep size graphically","TSMonitorLG",opt,&opt,PETSC_NULL);CHKERRQ(ierr);
101     if (opt) {
102       ierr = TSMonitorSet(ts,TSMonitorLG,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);
103     }
104     opt  = PETSC_FALSE;
105     ierr = PetscOptionsTruth("-ts_monitor_solution","Monitor solution graphically","TSMonitorSolution",opt,&opt,PETSC_NULL);CHKERRQ(ierr);
106     if (opt) {
107       ierr = TSMonitorSet(ts,TSMonitorSolution,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);
108     }
109 
110     /* Handle TS type options */
111     ierr = TSSetTypeFromOptions(ts);CHKERRQ(ierr);
112 
113     /* Handle specific TS options */
114     if (ts->ops->setfromoptions) {
115       ierr = (*ts->ops->setfromoptions)(ts);CHKERRQ(ierr);
116     }
117   ierr = PetscOptionsEnd();CHKERRQ(ierr);
118 
119   /* Handle subobject options */
120   switch(ts->problem_type) {
121     /* Should check for implicit/explicit */
122   case TS_LINEAR:
123     if (ts->ksp) {
124       ierr = KSPSetOperators(ts->ksp,ts->Arhs,ts->B,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr);
125       ierr = KSPSetFromOptions(ts->ksp);CHKERRQ(ierr);
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       ierr = SNESSetJacobian(ts->snes,ts->A?ts->A:ts->Arhs,ts->B,0,ts);CHKERRQ(ierr);
136       ierr = SNESSetFromOptions(ts->snes);CHKERRQ(ierr);
137     }
138     break;
139   default:
140     SETERRQ1(PETSC_ERR_ARG_WRONG, "Invalid problem type: %d", (int)ts->problem_type);
141   }
142 
143   PetscFunctionReturn(0);
144 }
145 
146 #undef  __FUNCT__
147 #define __FUNCT__ "TSViewFromOptions"
148 /*@
149   TSViewFromOptions - This function visualizes the ts based upon user options.
150 
151   Collective on TS
152 
153   Input Parameter:
154 . ts - The ts
155 
156   Level: intermediate
157 
158 .keywords: TS, view, options, database
159 .seealso: TSSetFromOptions(), TSView()
160 @*/
161 PetscErrorCode PETSCTS_DLLEXPORT 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];
167   PetscErrorCode ierr;
168 
169   PetscFunctionBegin;
170   ierr = PetscOptionsGetString(((PetscObject)ts)->prefix, "-ts_view", fileName, PETSC_MAX_PATH_LEN, &opt);CHKERRQ(ierr);
171   if (opt && !PetscPreLoadingOn) {
172     ierr = PetscViewerASCIIOpen(((PetscObject)ts)->comm,fileName,&viewer);CHKERRQ(ierr);
173     ierr = TSView(ts, viewer);CHKERRQ(ierr);
174     ierr = PetscViewerDestroy(viewer);CHKERRQ(ierr);
175   }
176   opt = PETSC_FALSE;
177   ierr = PetscOptionsGetTruth(((PetscObject)ts)->prefix, "-ts_view_draw", &opt,PETSC_NULL);CHKERRQ(ierr);
178   if (opt) {
179     ierr = PetscViewerDrawOpen(((PetscObject)ts)->comm, 0, 0, 0, 0, 300, 300, &viewer);CHKERRQ(ierr);
180     ierr = PetscViewerDrawGetDraw(viewer, 0, &draw);CHKERRQ(ierr);
181     if (title) {
182       ierr = PetscDrawSetTitle(draw, (char *)title);CHKERRQ(ierr);
183     } else {
184       ierr = PetscObjectName((PetscObject)ts);CHKERRQ(ierr);
185       ierr = PetscDrawSetTitle(draw, ((PetscObject)ts)->name);CHKERRQ(ierr);
186     }
187     ierr = TSView(ts, viewer);CHKERRQ(ierr);
188     ierr = PetscViewerFlush(viewer);CHKERRQ(ierr);
189     ierr = PetscDrawPause(draw);CHKERRQ(ierr);
190     ierr = PetscViewerDestroy(viewer);CHKERRQ(ierr);
191   }
192   PetscFunctionReturn(0);
193 }
194 
195 #undef __FUNCT__
196 #define __FUNCT__ "TSComputeRHSJacobian"
197 /*@
198    TSComputeRHSJacobian - Computes the Jacobian matrix that has been
199       set with TSSetRHSJacobian().
200 
201    Collective on TS and Vec
202 
203    Input Parameters:
204 +  ts - the TS context
205 .  t - current timestep
206 -  x - input vector
207 
208    Output Parameters:
209 +  A - Jacobian matrix
210 .  B - optional preconditioning matrix
211 -  flag - flag indicating matrix structure
212 
213    Notes:
214    Most users should not need to explicitly call this routine, as it
215    is used internally within the nonlinear solvers.
216 
217    See KSPSetOperators() for important information about setting the
218    flag parameter.
219 
220    TSComputeJacobian() is valid only for TS_NONLINEAR
221 
222    Level: developer
223 
224 .keywords: SNES, compute, Jacobian, matrix
225 
226 .seealso:  TSSetRHSJacobian(), KSPSetOperators()
227 @*/
228 PetscErrorCode PETSCTS_DLLEXPORT TSComputeRHSJacobian(TS ts,PetscReal t,Vec X,Mat *A,Mat *B,MatStructure *flg)
229 {
230   PetscErrorCode ierr;
231 
232   PetscFunctionBegin;
233   PetscValidHeaderSpecific(ts,TS_COOKIE,1);
234   PetscValidHeaderSpecific(X,VEC_COOKIE,3);
235   PetscCheckSameComm(ts,1,X,3);
236   if (ts->problem_type != TS_NONLINEAR) {
237     SETERRQ(PETSC_ERR_ARG_WRONG,"For TS_NONLINEAR only");
238   }
239   if (ts->ops->rhsjacobian) {
240     ierr = PetscLogEventBegin(TS_JacobianEval,ts,X,*A,*B);CHKERRQ(ierr);
241     *flg = DIFFERENT_NONZERO_PATTERN;
242     PetscStackPush("TS user Jacobian function");
243     ierr = (*ts->ops->rhsjacobian)(ts,t,X,A,B,flg,ts->jacP);CHKERRQ(ierr);
244     PetscStackPop;
245     ierr = PetscLogEventEnd(TS_JacobianEval,ts,X,*A,*B);CHKERRQ(ierr);
246     /* make sure user returned a correct Jacobian and preconditioner */
247     PetscValidHeaderSpecific(*A,MAT_COOKIE,4);
248     PetscValidHeaderSpecific(*B,MAT_COOKIE,5);
249   } else {
250     ierr = MatAssemblyBegin(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
251     ierr = MatAssemblyEnd(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
252     if (*A != *B) {
253       ierr = MatAssemblyBegin(*B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
254       ierr = MatAssemblyEnd(*B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
255     }
256   }
257   PetscFunctionReturn(0);
258 }
259 
260 #undef __FUNCT__
261 #define __FUNCT__ "TSComputeRHSFunction"
262 /*@
263    TSComputeRHSFunction - Evaluates the right-hand-side function.
264 
265    Collective on TS and Vec
266 
267    Input Parameters:
268 +  ts - the TS context
269 .  t - current time
270 -  x - state vector
271 
272    Output Parameter:
273 .  y - right hand side
274 
275    Note:
276    Most users should not need to explicitly call this routine, as it
277    is used internally within the nonlinear solvers.
278 
279    If the user did not provide a function but merely a matrix,
280    this routine applies the matrix.
281 
282    Level: developer
283 
284 .keywords: TS, compute
285 
286 .seealso: TSSetRHSFunction(), TSComputeIFunction()
287 @*/
288 PetscErrorCode TSComputeRHSFunction(TS ts,PetscReal t,Vec x,Vec y)
289 {
290   PetscErrorCode ierr;
291 
292   PetscFunctionBegin;
293   PetscValidHeaderSpecific(ts,TS_COOKIE,1);
294   PetscValidHeaderSpecific(x,VEC_COOKIE,3);
295   PetscValidHeaderSpecific(y,VEC_COOKIE,4);
296 
297   ierr = PetscLogEventBegin(TS_FunctionEval,ts,x,y,0);CHKERRQ(ierr);
298   if (ts->ops->rhsfunction) {
299     PetscStackPush("TS user right-hand-side function");
300     ierr = (*ts->ops->rhsfunction)(ts,t,x,y,ts->funP);CHKERRQ(ierr);
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       ierr = (*ts->ops->rhsmatrix)(ts,t,&ts->Arhs,&ts->B,&flg,ts->jacP);CHKERRQ(ierr);
307       PetscStackPop;
308     }
309     ierr = MatMult(ts->Arhs,x,y);CHKERRQ(ierr);
310   }
311 
312   ierr = PetscLogEventEnd(TS_FunctionEval,ts,x,y,0);CHKERRQ(ierr);
313 
314   PetscFunctionReturn(0);
315 }
316 
317 #undef __FUNCT__
318 #define __FUNCT__ "TSComputeIFunction"
319 /*@
320    TSComputeIFunction - Evaluates the DAE residual written in implicit form F(t,X,Xdot)=0
321 
322    Collective on TS and Vec
323 
324    Input Parameters:
325 +  ts - the TS context
326 .  t - current time
327 .  X - state vector
328 -  Xdot - time derivative of state vector
329 
330    Output Parameter:
331 .  Y - right hand side
332 
333    Note:
334    Most users should not need to explicitly call this routine, as it
335    is used internally within the nonlinear solvers.
336 
337    If the user did did not write their equations in implicit form, this
338    function recasts them in implicit form.
339 
340    Level: developer
341 
342 .keywords: TS, compute
343 
344 .seealso: TSSetIFunction(), TSComputeRHSFunction()
345 @*/
346 PetscErrorCode TSComputeIFunction(TS ts,PetscReal t,Vec X,Vec Xdot,Vec Y)
347 {
348   PetscErrorCode ierr;
349 
350   PetscFunctionBegin;
351   PetscValidHeaderSpecific(ts,TS_COOKIE,1);
352   PetscValidHeaderSpecific(X,VEC_COOKIE,3);
353   PetscValidHeaderSpecific(Xdot,VEC_COOKIE,4);
354   PetscValidHeaderSpecific(Y,VEC_COOKIE,5);
355 
356   ierr = PetscLogEventBegin(TS_FunctionEval,ts,X,Xdot,Y);CHKERRQ(ierr);
357   if (ts->ops->ifunction) {
358     PetscStackPush("TS user implicit function");
359     ierr = (*ts->ops->ifunction)(ts,t,X,Xdot,Y,ts->funP);CHKERRQ(ierr);
360     PetscStackPop;
361   } else {
362     if (ts->ops->rhsfunction) {
363       PetscStackPush("TS user right-hand-side function");
364       ierr = (*ts->ops->rhsfunction)(ts,t,X,Y,ts->funP);CHKERRQ(ierr);
365       PetscStackPop;
366     } else {
367       if (ts->ops->rhsmatrix) { /* assemble matrix for this timestep */
368         MatStructure flg;
369         PetscStackPush("TS user right-hand-side matrix function");
370         ierr = (*ts->ops->rhsmatrix)(ts,t,&ts->Arhs,&ts->B,&flg,ts->jacP);CHKERRQ(ierr);
371         PetscStackPop;
372       }
373       ierr = MatMult(ts->Arhs,X,Y);CHKERRQ(ierr);
374     }
375 
376     /* Convert to implicit form */
377     ierr = VecAYPX(Y,-1,Xdot);CHKERRQ(ierr);
378   }
379   ierr = PetscLogEventEnd(TS_FunctionEval,ts,X,Xdot,Y);CHKERRQ(ierr);
380   PetscFunctionReturn(0);
381 }
382 
383 #undef __FUNCT__
384 #define __FUNCT__ "TSComputeIJacobian"
385 /*@
386    TSComputeIJacobian - Evaluates the Jacobian of the DAE
387 
388    Collective on TS and Vec
389 
390    Input
391       Input Parameters:
392 +  ts - the TS context
393 .  t - current timestep
394 .  X - state vector
395 .  Xdot - time derivative of state vector
396 -  shift - shift to apply, see note below
397 
398    Output Parameters:
399 +  A - Jacobian matrix
400 .  B - optional preconditioning matrix
401 -  flag - flag indicating matrix structure
402 
403    Notes:
404    If F(t,X,Xdot)=0 is the DAE, the required Jacobian is
405 
406    dF/dX + shift*dF/dXdot
407 
408    Most users should not need to explicitly call this routine, as it
409    is used internally within the nonlinear solvers.
410 
411    TSComputeIJacobian() is valid only for TS_NONLINEAR
412 
413    Level: developer
414 
415 .keywords: TS, compute, Jacobian, matrix
416 
417 .seealso:  TSSetIJacobian()
418 @*/
419 PetscErrorCode PETSCTS_DLLEXPORT TSComputeIJacobian(TS ts,PetscReal t,Vec X,Vec Xdot,PetscReal shift,Mat *A,Mat *B,MatStructure *flg)
420 {
421   PetscErrorCode ierr;
422 
423   PetscFunctionBegin;
424   PetscValidHeaderSpecific(ts,TS_COOKIE,1);
425   PetscValidHeaderSpecific(X,VEC_COOKIE,3);
426   PetscValidHeaderSpecific(Xdot,VEC_COOKIE,4);
427   PetscValidPointer(A,6);
428   PetscValidHeaderSpecific(*A,MAT_COOKIE,6);
429   PetscValidPointer(B,7);
430   PetscValidHeaderSpecific(*B,MAT_COOKIE,7);
431   PetscValidPointer(flg,8);
432 
433   ierr = PetscLogEventBegin(TS_JacobianEval,ts,X,*A,*B);CHKERRQ(ierr);
434   if (ts->ops->ijacobian) {
435     PetscStackPush("TS user implicit Jacobian");
436     ierr = (*ts->ops->ijacobian)(ts,t,X,Xdot,shift,A,B,flg,ts->jacP);CHKERRQ(ierr);
437     PetscStackPop;
438   } else {
439     if (ts->ops->rhsjacobian) {
440       PetscStackPush("TS user right-hand-side Jacobian");
441       ierr = (*ts->ops->rhsjacobian)(ts,t,X,A,B,flg,ts->jacP);CHKERRQ(ierr);
442       PetscStackPop;
443     } else {
444       ierr = MatAssemblyBegin(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
445       ierr = MatAssemblyEnd(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
446       if (*A != *B) {
447         ierr = MatAssemblyBegin(*B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
448         ierr = MatAssemblyEnd(*B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
449       }
450     }
451 
452     /* Convert to implicit form */
453     /* inefficient because these operations will normally traverse all matrix elements twice */
454     ierr = MatScale(*A,-1);CHKERRQ(ierr);
455     ierr = MatShift(*A,shift);CHKERRQ(ierr);
456     if (*A != *B) {
457       ierr = MatScale(*B,-1);CHKERRQ(ierr);
458       ierr = MatShift(*B,shift);CHKERRQ(ierr);
459     }
460   }
461   ierr = PetscLogEventEnd(TS_JacobianEval,ts,X,*A,*B);CHKERRQ(ierr);
462   PetscFunctionReturn(0);
463 }
464 
465 #undef __FUNCT__
466 #define __FUNCT__ "TSSetRHSFunction"
467 /*@C
468     TSSetRHSFunction - Sets the routine for evaluating the function,
469     F(t,u), where U_t = F(t,u).
470 
471     Collective on TS
472 
473     Input Parameters:
474 +   ts - the TS context obtained from TSCreate()
475 .   f - routine for evaluating the right-hand-side function
476 -   ctx - [optional] user-defined context for private data for the
477           function evaluation routine (may be PETSC_NULL)
478 
479     Calling sequence of func:
480 $     func (TS ts,PetscReal t,Vec u,Vec F,void *ctx);
481 
482 +   t - current timestep
483 .   u - input vector
484 .   F - function vector
485 -   ctx - [optional] user-defined function context
486 
487     Important:
488     The user MUST call either this routine or TSSetMatrices().
489 
490     Level: beginner
491 
492 .keywords: TS, timestep, set, right-hand-side, function
493 
494 .seealso: TSSetMatrices()
495 @*/
496 PetscErrorCode PETSCTS_DLLEXPORT TSSetRHSFunction(TS ts,PetscErrorCode (*f)(TS,PetscReal,Vec,Vec,void*),void *ctx)
497 {
498   PetscFunctionBegin;
499 
500   PetscValidHeaderSpecific(ts,TS_COOKIE,1);
501   if (ts->problem_type == TS_LINEAR) {
502     SETERRQ(PETSC_ERR_ARG_WRONG,"Cannot set function for linear problem");
503   }
504   ts->ops->rhsfunction = f;
505   ts->funP             = ctx;
506   PetscFunctionReturn(0);
507 }
508 
509 #undef __FUNCT__
510 #define __FUNCT__ "TSSetMatrices"
511 /*@C
512    TSSetMatrices - Sets the functions to compute the matrices Alhs and Arhs,
513    where Alhs(t) U_t = Arhs(t) U.
514 
515    Collective on TS
516 
517    Input Parameters:
518 +  ts   - the TS context obtained from TSCreate()
519 .  Arhs - matrix
520 .  frhs - the matrix evaluation routine for Arhs; use PETSC_NULL (PETSC_NULL_FUNCTION in fortran)
521           if Arhs is not a function of t.
522 .  Alhs - matrix or PETSC_NULL if Alhs is an indentity matrix.
523 .  flhs - the matrix evaluation routine for Alhs; use PETSC_NULL (PETSC_NULL_FUNCTION in fortran)
524           if Alhs is not a function of t.
525 .  flag - flag indicating information about the matrix structure of Arhs and Alhs.
526           The available options are
527             SAME_NONZERO_PATTERN - Alhs has the same nonzero structure as Arhs
528             DIFFERENT_NONZERO_PATTERN - Alhs has different nonzero structure as Arhs
529 -  ctx  - [optional] user-defined context for private data for the
530           matrix evaluation routine (may be PETSC_NULL)
531 
532    Calling sequence of func:
533 $     func(TS ts,PetscReal t,Mat *A,Mat *B,PetscInt *flag,void *ctx);
534 
535 +  t - current timestep
536 .  A - matrix A, where U_t = A(t) U
537 .  B - preconditioner matrix, usually the same as A
538 .  flag - flag indicating information about the preconditioner matrix
539           structure (same as flag in KSPSetOperators())
540 -  ctx - [optional] user-defined context for matrix evaluation routine
541 
542    Notes:
543    The routine func() takes Mat* as the matrix arguments rather than Mat.
544    This allows the matrix evaluation routine to replace Arhs or Alhs with a
545    completely new new matrix structure (not just different matrix elements)
546    when appropriate, for instance, if the nonzero structure is changing
547    throughout the global iterations.
548 
549    Important:
550    The user MUST call either this routine or TSSetRHSFunction().
551 
552    Level: beginner
553 
554 .keywords: TS, timestep, set, matrix
555 
556 .seealso: TSSetRHSFunction()
557 @*/
558 PetscErrorCode PETSCTS_DLLEXPORT 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)
559 {
560   PetscFunctionBegin;
561   PetscValidHeaderSpecific(ts,TS_COOKIE,1);
562   if (Arhs){
563     PetscValidHeaderSpecific(Arhs,MAT_COOKIE,2);
564     PetscCheckSameComm(ts,1,Arhs,2);
565     ts->Arhs           = Arhs;
566     ts->ops->rhsmatrix = frhs;
567   }
568   if (Alhs){
569     PetscValidHeaderSpecific(Alhs,MAT_COOKIE,4);
570     PetscCheckSameComm(ts,1,Alhs,4);
571     ts->Alhs           = Alhs;
572     ts->ops->lhsmatrix = flhs;
573   }
574 
575   ts->jacP           = ctx;
576   ts->matflg         = flag;
577   PetscFunctionReturn(0);
578 }
579 
580 #undef __FUNCT__
581 #define __FUNCT__ "TSGetMatrices"
582 /*@C
583    TSGetMatrices - Returns the matrices Arhs and Alhs at the present timestep,
584    where Alhs(t) U_t = Arhs(t) U.
585 
586    Not Collective, but parallel objects are returned if TS is parallel
587 
588    Input Parameter:
589 .  ts  - The TS context obtained from TSCreate()
590 
591    Output Parameters:
592 +  Arhs - The right-hand side matrix
593 .  Alhs - The left-hand side matrix
594 -  ctx - User-defined context for matrix evaluation routine
595 
596    Notes: You can pass in PETSC_NULL for any return argument you do not need.
597 
598    Level: intermediate
599 
600 .seealso: TSSetMatrices(), TSGetTimeStep(), TSGetTime(), TSGetTimeStepNumber(), TSGetRHSJacobian()
601 
602 .keywords: TS, timestep, get, matrix
603 
604 @*/
605 PetscErrorCode PETSCTS_DLLEXPORT TSGetMatrices(TS ts,Mat *Arhs,Mat *Alhs,void **ctx)
606 {
607   PetscFunctionBegin;
608   PetscValidHeaderSpecific(ts,TS_COOKIE,1);
609   if (Arhs) *Arhs = ts->Arhs;
610   if (Alhs) *Alhs = ts->Alhs;
611   if (ctx)  *ctx = ts->jacP;
612   PetscFunctionReturn(0);
613 }
614 
615 #undef __FUNCT__
616 #define __FUNCT__ "TSSetRHSJacobian"
617 /*@C
618    TSSetRHSJacobian - Sets the function to compute the Jacobian of F,
619    where U_t = F(U,t), as well as the location to store the matrix.
620    Use TSSetMatrices() for linear problems.
621 
622    Collective on TS
623 
624    Input Parameters:
625 +  ts  - the TS context obtained from TSCreate()
626 .  A   - Jacobian matrix
627 .  B   - preconditioner matrix (usually same as A)
628 .  f   - the Jacobian evaluation routine
629 -  ctx - [optional] user-defined context for private data for the
630          Jacobian evaluation routine (may be PETSC_NULL)
631 
632    Calling sequence of func:
633 $     func (TS ts,PetscReal t,Vec u,Mat *A,Mat *B,MatStructure *flag,void *ctx);
634 
635 +  t - current timestep
636 .  u - input vector
637 .  A - matrix A, where U_t = A(t)u
638 .  B - preconditioner matrix, usually the same as A
639 .  flag - flag indicating information about the preconditioner matrix
640           structure (same as flag in KSPSetOperators())
641 -  ctx - [optional] user-defined context for matrix evaluation routine
642 
643    Notes:
644    See KSPSetOperators() for important information about setting the flag
645    output parameter in the routine func().  Be sure to read this information!
646 
647    The routine func() takes Mat * as the matrix arguments rather than Mat.
648    This allows the matrix evaluation routine to replace A and/or B with a
649    completely new matrix structure (not just different matrix elements)
650    when appropriate, for instance, if the nonzero structure is changing
651    throughout the global iterations.
652 
653    Level: beginner
654 
655 .keywords: TS, timestep, set, right-hand-side, Jacobian
656 
657 .seealso: TSDefaultComputeJacobianColor(),
658           SNESDefaultComputeJacobianColor(), TSSetRHSFunction(), TSSetMatrices()
659 
660 @*/
661 PetscErrorCode PETSCTS_DLLEXPORT TSSetRHSJacobian(TS ts,Mat A,Mat B,PetscErrorCode (*f)(TS,PetscReal,Vec,Mat*,Mat*,MatStructure*,void*),void *ctx)
662 {
663   PetscFunctionBegin;
664   PetscValidHeaderSpecific(ts,TS_COOKIE,1);
665   PetscValidHeaderSpecific(A,MAT_COOKIE,2);
666   PetscValidHeaderSpecific(B,MAT_COOKIE,3);
667   PetscCheckSameComm(ts,1,A,2);
668   PetscCheckSameComm(ts,1,B,3);
669   if (ts->problem_type != TS_NONLINEAR) {
670     SETERRQ(PETSC_ERR_ARG_WRONG,"Not for linear problems; use TSSetMatrices()");
671   }
672 
673   ts->ops->rhsjacobian = f;
674   ts->jacP             = ctx;
675   ts->Arhs             = A;
676   ts->B                = B;
677   PetscFunctionReturn(0);
678 }
679 
680 
681 #undef __FUNCT__
682 #define __FUNCT__ "TSSetIFunction"
683 /*@C
684    TSSetIFunction - Set the function to compute F(t,U,U_t) where F = 0 is the DAE to be solved.
685 
686    Collective on TS
687 
688    Input Parameters:
689 +  ts  - the TS context obtained from TSCreate()
690 .  f   - the function evaluation routine
691 -  ctx - user-defined context for private data for the function evaluation routine (may be PETSC_NULL)
692 
693    Calling sequence of f:
694 $  f(TS ts,PetscReal t,Vec u,Vec u_t,Vec F,ctx);
695 
696 +  t   - time at step/stage being solved
697 .  u   - state vector
698 .  u_t - time derivative of state vector
699 .  F   - function vector
700 -  ctx - [optional] user-defined context for matrix evaluation routine
701 
702    Important:
703    The user MUST call either this routine, TSSetRHSFunction(), or TSSetMatrices().  This routine must be used when not solving an ODE.
704 
705    Level: beginner
706 
707 .keywords: TS, timestep, set, DAE, Jacobian
708 
709 .seealso: TSSetMatrices(), TSSetRHSFunction(), TSSetIJacobian()
710 @*/
711 PetscErrorCode PETSCTS_DLLEXPORT TSSetIFunction(TS ts,TSIFunction f,void *ctx)
712 {
713 
714   PetscFunctionBegin;
715   PetscValidHeaderSpecific(ts,TS_COOKIE,1);
716   ts->ops->ifunction = f;
717   ts->funP           = ctx;
718   PetscFunctionReturn(0);
719 }
720 
721 #undef __FUNCT__
722 #define __FUNCT__ "TSSetIJacobian"
723 /*@C
724    TSSetIJacobian - Set the function to compute the Jacobian of
725    G(U) = F(t,U,U0+a*U) where F(t,U,U_t) = 0 is the DAE to be solved.
726 
727    Collective on TS
728 
729    Input Parameters:
730 +  ts  - the TS context obtained from TSCreate()
731 .  A   - Jacobian matrix
732 .  B   - preconditioning matrix for A (may be same as A)
733 .  f   - the Jacobian evaluation routine
734 -  ctx - user-defined context for private data for the Jacobian evaluation routine (may be PETSC_NULL)
735 
736    Calling sequence of f:
737 $  f(TS ts,PetscReal t,Vec u,Vec u_t,PetscReal a,Mat *A,Mat *B,MatStructure *flag,void *ctx);
738 
739 +  t    - time at step/stage being solved
740 .  u    - state vector
741 .  u_t  - time derivative of state vector
742 .  a    - shift
743 .  A    - Jacobian of G(U) = F(t,U,U0+a*U), equivalent to dF/dU + a*dF/dU_t
744 .  B    - preconditioning matrix for A, may be same as A
745 .  flag - flag indicating information about the preconditioner matrix
746           structure (same as flag in KSPSetOperators())
747 -  ctx  - [optional] user-defined context for matrix evaluation routine
748 
749    Notes:
750    The matrices A and B are exactly the matrices that are used by SNES for the nonlinear solve.
751 
752    Level: beginner
753 
754 .keywords: TS, timestep, DAE, Jacobian
755 
756 .seealso: TSSetIFunction(), TSSetRHSJacobian()
757 
758 @*/
759 PetscErrorCode PETSCTS_DLLEXPORT TSSetIJacobian(TS ts,Mat A,Mat B,TSIJacobian f,void *ctx)
760 {
761   PetscErrorCode ierr;
762 
763   PetscFunctionBegin;
764   PetscValidHeaderSpecific(ts,TS_COOKIE,1);
765   if (A) PetscValidHeaderSpecific(A,MAT_COOKIE,2);
766   if (B) PetscValidHeaderSpecific(B,MAT_COOKIE,3);
767   if (A) PetscCheckSameComm(ts,1,A,2);
768   if (B) PetscCheckSameComm(ts,1,B,3);
769   if (f)   ts->ops->ijacobian = f;
770   if (ctx) ts->jacP             = ctx;
771   if (A) {
772     ierr = PetscObjectReference((PetscObject)A);CHKERRQ(ierr);
773     if (ts->A) {ierr = MatDestroy(ts->A);CHKERRQ(ierr);}
774     ts->A = A;
775   }
776 #if 0
777   /* The sane and consistent alternative */
778   if (B) {
779     ierr = PetscObjectReference((PetscObject)B);CHKERRQ(ierr);
780     if (ts->B) {ierr = MatDestroy(ts->B);CHKERRQ(ierr);}
781     ts->B = B;
782   }
783 #else
784   /* Don't reference B because TSDestroy() doesn't destroy it.  These ownership semantics are awkward and inconsistent. */
785   if (B) ts->B = B;
786 #endif
787   PetscFunctionReturn(0);
788 }
789 
790 #undef __FUNCT__
791 #define __FUNCT__ "TSView"
792 /*@C
793     TSView - Prints the TS data structure.
794 
795     Collective on TS
796 
797     Input Parameters:
798 +   ts - the TS context obtained from TSCreate()
799 -   viewer - visualization context
800 
801     Options Database Key:
802 .   -ts_view - calls TSView() at end of TSStep()
803 
804     Notes:
805     The available visualization contexts include
806 +     PETSC_VIEWER_STDOUT_SELF - standard output (default)
807 -     PETSC_VIEWER_STDOUT_WORLD - synchronized standard
808          output where only the first processor opens
809          the file.  All other processors send their
810          data to the first processor to print.
811 
812     The user can open an alternative visualization context with
813     PetscViewerASCIIOpen() - output to a specified file.
814 
815     Level: beginner
816 
817 .keywords: TS, timestep, view
818 
819 .seealso: PetscViewerASCIIOpen()
820 @*/
821 PetscErrorCode PETSCTS_DLLEXPORT TSView(TS ts,PetscViewer viewer)
822 {
823   PetscErrorCode ierr;
824   const TSType   type;
825   PetscTruth     iascii,isstring;
826 
827   PetscFunctionBegin;
828   PetscValidHeaderSpecific(ts,TS_COOKIE,1);
829   if (!viewer) {
830     ierr = PetscViewerASCIIGetStdout(((PetscObject)ts)->comm,&viewer);CHKERRQ(ierr);
831   }
832   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_COOKIE,2);
833   PetscCheckSameComm(ts,1,viewer,2);
834 
835   ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&iascii);CHKERRQ(ierr);
836   ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_STRING,&isstring);CHKERRQ(ierr);
837   if (iascii) {
838     ierr = PetscViewerASCIIPrintf(viewer,"TS Object:\n");CHKERRQ(ierr);
839     ierr = TSGetType(ts,&type);CHKERRQ(ierr);
840     if (type) {
841       ierr = PetscViewerASCIIPrintf(viewer,"  type: %s\n",type);CHKERRQ(ierr);
842     } else {
843       ierr = PetscViewerASCIIPrintf(viewer,"  type: not yet set\n");CHKERRQ(ierr);
844     }
845     if (ts->ops->view) {
846       ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
847       ierr = (*ts->ops->view)(ts,viewer);CHKERRQ(ierr);
848       ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
849     }
850     ierr = PetscViewerASCIIPrintf(viewer,"  maximum steps=%D\n",ts->max_steps);CHKERRQ(ierr);
851     ierr = PetscViewerASCIIPrintf(viewer,"  maximum time=%G\n",ts->max_time);CHKERRQ(ierr);
852     if (ts->problem_type == TS_NONLINEAR) {
853       ierr = PetscViewerASCIIPrintf(viewer,"  total number of nonlinear solver iterations=%D\n",ts->nonlinear_its);CHKERRQ(ierr);
854     }
855     ierr = PetscViewerASCIIPrintf(viewer,"  total number of linear solver iterations=%D\n",ts->linear_its);CHKERRQ(ierr);
856   } else if (isstring) {
857     ierr = TSGetType(ts,&type);CHKERRQ(ierr);
858     ierr = PetscViewerStringSPrintf(viewer," %-7.7s",type);CHKERRQ(ierr);
859   }
860   ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
861   if (ts->ksp) {ierr = KSPView(ts->ksp,viewer);CHKERRQ(ierr);}
862   if (ts->snes) {ierr = SNESView(ts->snes,viewer);CHKERRQ(ierr);}
863   ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
864   PetscFunctionReturn(0);
865 }
866 
867 
868 #undef __FUNCT__
869 #define __FUNCT__ "TSSetApplicationContext"
870 /*@C
871    TSSetApplicationContext - Sets an optional user-defined context for
872    the timesteppers.
873 
874    Collective on TS
875 
876    Input Parameters:
877 +  ts - the TS context obtained from TSCreate()
878 -  usrP - optional user context
879 
880    Level: intermediate
881 
882 .keywords: TS, timestep, set, application, context
883 
884 .seealso: TSGetApplicationContext()
885 @*/
886 PetscErrorCode PETSCTS_DLLEXPORT TSSetApplicationContext(TS ts,void *usrP)
887 {
888   PetscFunctionBegin;
889   PetscValidHeaderSpecific(ts,TS_COOKIE,1);
890   ts->user = usrP;
891   PetscFunctionReturn(0);
892 }
893 
894 #undef __FUNCT__
895 #define __FUNCT__ "TSGetApplicationContext"
896 /*@C
897     TSGetApplicationContext - Gets the user-defined context for the
898     timestepper.
899 
900     Not Collective
901 
902     Input Parameter:
903 .   ts - the TS context obtained from TSCreate()
904 
905     Output Parameter:
906 .   usrP - user context
907 
908     Level: intermediate
909 
910 .keywords: TS, timestep, get, application, context
911 
912 .seealso: TSSetApplicationContext()
913 @*/
914 PetscErrorCode PETSCTS_DLLEXPORT TSGetApplicationContext(TS ts,void **usrP)
915 {
916   PetscFunctionBegin;
917   PetscValidHeaderSpecific(ts,TS_COOKIE,1);
918   *usrP = ts->user;
919   PetscFunctionReturn(0);
920 }
921 
922 #undef __FUNCT__
923 #define __FUNCT__ "TSGetTimeStepNumber"
924 /*@
925    TSGetTimeStepNumber - Gets the current number of timesteps.
926 
927    Not Collective
928 
929    Input Parameter:
930 .  ts - the TS context obtained from TSCreate()
931 
932    Output Parameter:
933 .  iter - number steps so far
934 
935    Level: intermediate
936 
937 .keywords: TS, timestep, get, iteration, number
938 @*/
939 PetscErrorCode PETSCTS_DLLEXPORT TSGetTimeStepNumber(TS ts,PetscInt* iter)
940 {
941   PetscFunctionBegin;
942   PetscValidHeaderSpecific(ts,TS_COOKIE,1);
943   PetscValidIntPointer(iter,2);
944   *iter = ts->steps;
945   PetscFunctionReturn(0);
946 }
947 
948 #undef __FUNCT__
949 #define __FUNCT__ "TSSetInitialTimeStep"
950 /*@
951    TSSetInitialTimeStep - Sets the initial timestep to be used,
952    as well as the initial time.
953 
954    Collective on TS
955 
956    Input Parameters:
957 +  ts - the TS context obtained from TSCreate()
958 .  initial_time - the initial time
959 -  time_step - the size of the timestep
960 
961    Level: intermediate
962 
963 .seealso: TSSetTimeStep(), TSGetTimeStep()
964 
965 .keywords: TS, set, initial, timestep
966 @*/
967 PetscErrorCode PETSCTS_DLLEXPORT TSSetInitialTimeStep(TS ts,PetscReal initial_time,PetscReal time_step)
968 {
969   PetscFunctionBegin;
970   PetscValidHeaderSpecific(ts,TS_COOKIE,1);
971   ts->time_step         = time_step;
972   ts->initial_time_step = time_step;
973   ts->ptime             = initial_time;
974   PetscFunctionReturn(0);
975 }
976 
977 #undef __FUNCT__
978 #define __FUNCT__ "TSSetTimeStep"
979 /*@
980    TSSetTimeStep - Allows one to reset the timestep at any time,
981    useful for simple pseudo-timestepping codes.
982 
983    Collective on TS
984 
985    Input Parameters:
986 +  ts - the TS context obtained from TSCreate()
987 -  time_step - the size of the timestep
988 
989    Level: intermediate
990 
991 .seealso: TSSetInitialTimeStep(), TSGetTimeStep()
992 
993 .keywords: TS, set, timestep
994 @*/
995 PetscErrorCode PETSCTS_DLLEXPORT TSSetTimeStep(TS ts,PetscReal time_step)
996 {
997   PetscFunctionBegin;
998   PetscValidHeaderSpecific(ts,TS_COOKIE,1);
999   ts->time_step = time_step;
1000   PetscFunctionReturn(0);
1001 }
1002 
1003 #undef __FUNCT__
1004 #define __FUNCT__ "TSGetTimeStep"
1005 /*@
1006    TSGetTimeStep - Gets the current timestep size.
1007 
1008    Not Collective
1009 
1010    Input Parameter:
1011 .  ts - the TS context obtained from TSCreate()
1012 
1013    Output Parameter:
1014 .  dt - the current timestep size
1015 
1016    Level: intermediate
1017 
1018 .seealso: TSSetInitialTimeStep(), TSGetTimeStep()
1019 
1020 .keywords: TS, get, timestep
1021 @*/
1022 PetscErrorCode PETSCTS_DLLEXPORT TSGetTimeStep(TS ts,PetscReal* dt)
1023 {
1024   PetscFunctionBegin;
1025   PetscValidHeaderSpecific(ts,TS_COOKIE,1);
1026   PetscValidDoublePointer(dt,2);
1027   *dt = ts->time_step;
1028   PetscFunctionReturn(0);
1029 }
1030 
1031 #undef __FUNCT__
1032 #define __FUNCT__ "TSGetSolution"
1033 /*@
1034    TSGetSolution - Returns the solution at the present timestep. It
1035    is valid to call this routine inside the function that you are evaluating
1036    in order to move to the new timestep. This vector not changed until
1037    the solution at the next timestep has been calculated.
1038 
1039    Not Collective, but Vec returned is parallel if TS is parallel
1040 
1041    Input Parameter:
1042 .  ts - the TS context obtained from TSCreate()
1043 
1044    Output Parameter:
1045 .  v - the vector containing the solution
1046 
1047    Level: intermediate
1048 
1049 .seealso: TSGetTimeStep()
1050 
1051 .keywords: TS, timestep, get, solution
1052 @*/
1053 PetscErrorCode PETSCTS_DLLEXPORT TSGetSolution(TS ts,Vec *v)
1054 {
1055   PetscFunctionBegin;
1056   PetscValidHeaderSpecific(ts,TS_COOKIE,1);
1057   PetscValidPointer(v,2);
1058   *v = ts->vec_sol_always;
1059   PetscFunctionReturn(0);
1060 }
1061 
1062 /* ----- Routines to initialize and destroy a timestepper ---- */
1063 #undef __FUNCT__
1064 #define __FUNCT__ "TSSetProblemType"
1065 /*@
1066   TSSetProblemType - Sets the type of problem to be solved.
1067 
1068   Not collective
1069 
1070   Input Parameters:
1071 + ts   - The TS
1072 - type - One of TS_LINEAR, TS_NONLINEAR where these types refer to problems of the forms
1073 .vb
1074          U_t = A U
1075          U_t = A(t) U
1076          U_t = F(t,U)
1077 .ve
1078 
1079    Level: beginner
1080 
1081 .keywords: TS, problem type
1082 .seealso: TSSetUp(), TSProblemType, TS
1083 @*/
1084 PetscErrorCode PETSCTS_DLLEXPORT TSSetProblemType(TS ts, TSProblemType type)
1085 {
1086   PetscFunctionBegin;
1087   PetscValidHeaderSpecific(ts, TS_COOKIE,1);
1088   ts->problem_type = type;
1089   PetscFunctionReturn(0);
1090 }
1091 
1092 #undef __FUNCT__
1093 #define __FUNCT__ "TSGetProblemType"
1094 /*@C
1095   TSGetProblemType - Gets the type of problem to be solved.
1096 
1097   Not collective
1098 
1099   Input Parameter:
1100 . ts   - The TS
1101 
1102   Output Parameter:
1103 . type - One of TS_LINEAR, TS_NONLINEAR where these types refer to problems of the forms
1104 .vb
1105          U_t = A U
1106          U_t = A(t) U
1107          U_t = F(t,U)
1108 .ve
1109 
1110    Level: beginner
1111 
1112 .keywords: TS, problem type
1113 .seealso: TSSetUp(), TSProblemType, TS
1114 @*/
1115 PetscErrorCode PETSCTS_DLLEXPORT TSGetProblemType(TS ts, TSProblemType *type)
1116 {
1117   PetscFunctionBegin;
1118   PetscValidHeaderSpecific(ts, TS_COOKIE,1);
1119   PetscValidIntPointer(type,2);
1120   *type = ts->problem_type;
1121   PetscFunctionReturn(0);
1122 }
1123 
1124 #undef __FUNCT__
1125 #define __FUNCT__ "TSSetUp"
1126 /*@
1127    TSSetUp - Sets up the internal data structures for the later use
1128    of a timestepper.
1129 
1130    Collective on TS
1131 
1132    Input Parameter:
1133 .  ts - the TS context obtained from TSCreate()
1134 
1135    Notes:
1136    For basic use of the TS solvers the user need not explicitly call
1137    TSSetUp(), since these actions will automatically occur during
1138    the call to TSStep().  However, if one wishes to control this
1139    phase separately, TSSetUp() should be called after TSCreate()
1140    and optional routines of the form TSSetXXX(), but before TSStep().
1141 
1142    Level: advanced
1143 
1144 .keywords: TS, timestep, setup
1145 
1146 .seealso: TSCreate(), TSStep(), TSDestroy()
1147 @*/
1148 PetscErrorCode PETSCTS_DLLEXPORT TSSetUp(TS ts)
1149 {
1150   PetscErrorCode ierr;
1151 
1152   PetscFunctionBegin;
1153   PetscValidHeaderSpecific(ts,TS_COOKIE,1);
1154   if (!ts->vec_sol) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Must call TSSetSolution() first");
1155   if (!((PetscObject)ts)->type_name) {
1156     ierr = TSSetType(ts,TSEULER);CHKERRQ(ierr);
1157   }
1158   ierr = (*ts->ops->setup)(ts);CHKERRQ(ierr);
1159   ts->setupcalled = 1;
1160   PetscFunctionReturn(0);
1161 }
1162 
1163 #undef __FUNCT__
1164 #define __FUNCT__ "TSDestroy"
1165 /*@
1166    TSDestroy - Destroys the timestepper context that was created
1167    with TSCreate().
1168 
1169    Collective on TS
1170 
1171    Input Parameter:
1172 .  ts - the TS context obtained from TSCreate()
1173 
1174    Level: beginner
1175 
1176 .keywords: TS, timestepper, destroy
1177 
1178 .seealso: TSCreate(), TSSetUp(), TSSolve()
1179 @*/
1180 PetscErrorCode PETSCTS_DLLEXPORT TSDestroy(TS ts)
1181 {
1182   PetscErrorCode ierr;
1183 
1184   PetscFunctionBegin;
1185   PetscValidHeaderSpecific(ts,TS_COOKIE,1);
1186   if (--((PetscObject)ts)->refct > 0) PetscFunctionReturn(0);
1187 
1188   /* if memory was published with AMS then destroy it */
1189   ierr = PetscObjectDepublish(ts);CHKERRQ(ierr);
1190   if (ts->A) {ierr = MatDestroy(ts->A);CHKERRQ(ierr)}
1191   if (ts->ksp) {ierr = KSPDestroy(ts->ksp);CHKERRQ(ierr);}
1192   if (ts->snes) {ierr = SNESDestroy(ts->snes);CHKERRQ(ierr);}
1193   if (ts->ops->destroy) {ierr = (*(ts)->ops->destroy)(ts);CHKERRQ(ierr);}
1194   ierr = TSMonitorCancel(ts);CHKERRQ(ierr);
1195   ierr = PetscHeaderDestroy(ts);CHKERRQ(ierr);
1196   PetscFunctionReturn(0);
1197 }
1198 
1199 #undef __FUNCT__
1200 #define __FUNCT__ "TSGetSNES"
1201 /*@
1202    TSGetSNES - Returns the SNES (nonlinear solver) associated with
1203    a TS (timestepper) context. Valid only for nonlinear problems.
1204 
1205    Not Collective, but SNES is parallel if TS is parallel
1206 
1207    Input Parameter:
1208 .  ts - the TS context obtained from TSCreate()
1209 
1210    Output Parameter:
1211 .  snes - the nonlinear solver context
1212 
1213    Notes:
1214    The user can then directly manipulate the SNES context to set various
1215    options, etc.  Likewise, the user can then extract and manipulate the
1216    KSP, KSP, and PC contexts as well.
1217 
1218    TSGetSNES() does not work for integrators that do not use SNES; in
1219    this case TSGetSNES() returns PETSC_NULL in snes.
1220 
1221    Level: beginner
1222 
1223 .keywords: timestep, get, SNES
1224 @*/
1225 PetscErrorCode PETSCTS_DLLEXPORT TSGetSNES(TS ts,SNES *snes)
1226 {
1227   PetscFunctionBegin;
1228   PetscValidHeaderSpecific(ts,TS_COOKIE,1);
1229   PetscValidPointer(snes,2);
1230   if (((PetscObject)ts)->type_name == PETSC_NULL)
1231     SETERRQ(PETSC_ERR_ARG_NULL,"SNES is not created yet. Call TSSetType() first");
1232   if (ts->problem_type == TS_LINEAR) SETERRQ(PETSC_ERR_ARG_WRONG,"Nonlinear only; use TSGetKSP()");
1233   *snes = ts->snes;
1234   PetscFunctionReturn(0);
1235 }
1236 
1237 #undef __FUNCT__
1238 #define __FUNCT__ "TSGetKSP"
1239 /*@
1240    TSGetKSP - Returns the KSP (linear solver) associated with
1241    a TS (timestepper) context.
1242 
1243    Not Collective, but KSP is parallel if TS is parallel
1244 
1245    Input Parameter:
1246 .  ts - the TS context obtained from TSCreate()
1247 
1248    Output Parameter:
1249 .  ksp - the nonlinear solver context
1250 
1251    Notes:
1252    The user can then directly manipulate the KSP context to set various
1253    options, etc.  Likewise, the user can then extract and manipulate the
1254    KSP and PC contexts as well.
1255 
1256    TSGetKSP() does not work for integrators that do not use KSP;
1257    in this case TSGetKSP() returns PETSC_NULL in ksp.
1258 
1259    Level: beginner
1260 
1261 .keywords: timestep, get, KSP
1262 @*/
1263 PetscErrorCode PETSCTS_DLLEXPORT TSGetKSP(TS ts,KSP *ksp)
1264 {
1265   PetscFunctionBegin;
1266   PetscValidHeaderSpecific(ts,TS_COOKIE,1);
1267   PetscValidPointer(ksp,2);
1268   if (((PetscObject)ts)->type_name == PETSC_NULL)
1269     SETERRQ(PETSC_ERR_ARG_NULL,"KSP is not created yet. Call TSSetType() first");
1270   if (ts->problem_type != TS_LINEAR) SETERRQ(PETSC_ERR_ARG_WRONG,"Linear only; use TSGetSNES()");
1271   *ksp = ts->ksp;
1272   PetscFunctionReturn(0);
1273 }
1274 
1275 /* ----------- Routines to set solver parameters ---------- */
1276 
1277 #undef __FUNCT__
1278 #define __FUNCT__ "TSGetDuration"
1279 /*@
1280    TSGetDuration - Gets the maximum number of timesteps to use and
1281    maximum time for iteration.
1282 
1283    Collective on TS
1284 
1285    Input Parameters:
1286 +  ts       - the TS context obtained from TSCreate()
1287 .  maxsteps - maximum number of iterations to use, or PETSC_NULL
1288 -  maxtime  - final time to iterate to, or PETSC_NULL
1289 
1290    Level: intermediate
1291 
1292 .keywords: TS, timestep, get, maximum, iterations, time
1293 @*/
1294 PetscErrorCode PETSCTS_DLLEXPORT TSGetDuration(TS ts, PetscInt *maxsteps, PetscReal *maxtime)
1295 {
1296   PetscFunctionBegin;
1297   PetscValidHeaderSpecific(ts, TS_COOKIE,1);
1298   if (maxsteps) {
1299     PetscValidIntPointer(maxsteps,2);
1300     *maxsteps = ts->max_steps;
1301   }
1302   if (maxtime ) {
1303     PetscValidScalarPointer(maxtime,3);
1304     *maxtime  = ts->max_time;
1305   }
1306   PetscFunctionReturn(0);
1307 }
1308 
1309 #undef __FUNCT__
1310 #define __FUNCT__ "TSSetDuration"
1311 /*@
1312    TSSetDuration - Sets the maximum number of timesteps to use and
1313    maximum time for iteration.
1314 
1315    Collective on TS
1316 
1317    Input Parameters:
1318 +  ts - the TS context obtained from TSCreate()
1319 .  maxsteps - maximum number of iterations to use
1320 -  maxtime - final time to iterate to
1321 
1322    Options Database Keys:
1323 .  -ts_max_steps <maxsteps> - Sets maxsteps
1324 .  -ts_max_time <maxtime> - Sets maxtime
1325 
1326    Notes:
1327    The default maximum number of iterations is 5000. Default time is 5.0
1328 
1329    Level: intermediate
1330 
1331 .keywords: TS, timestep, set, maximum, iterations
1332 @*/
1333 PetscErrorCode PETSCTS_DLLEXPORT TSSetDuration(TS ts,PetscInt maxsteps,PetscReal maxtime)
1334 {
1335   PetscFunctionBegin;
1336   PetscValidHeaderSpecific(ts,TS_COOKIE,1);
1337   ts->max_steps = maxsteps;
1338   ts->max_time  = maxtime;
1339   PetscFunctionReturn(0);
1340 }
1341 
1342 #undef __FUNCT__
1343 #define __FUNCT__ "TSSetSolution"
1344 /*@
1345    TSSetSolution - Sets the initial solution vector
1346    for use by the TS routines.
1347 
1348    Collective on TS and Vec
1349 
1350    Input Parameters:
1351 +  ts - the TS context obtained from TSCreate()
1352 -  x - the solution vector
1353 
1354    Level: beginner
1355 
1356 .keywords: TS, timestep, set, solution, initial conditions
1357 @*/
1358 PetscErrorCode PETSCTS_DLLEXPORT TSSetSolution(TS ts,Vec x)
1359 {
1360   PetscFunctionBegin;
1361   PetscValidHeaderSpecific(ts,TS_COOKIE,1);
1362   PetscValidHeaderSpecific(x,VEC_COOKIE,2);
1363   ts->vec_sol        = ts->vec_sol_always = x;
1364   PetscFunctionReturn(0);
1365 }
1366 
1367 #undef __FUNCT__
1368 #define __FUNCT__ "TSSetPreStep"
1369 /*@C
1370   TSSetPreStep - Sets the general-purpose function
1371   called once at the beginning of each time step.
1372 
1373   Collective on TS
1374 
1375   Input Parameters:
1376 + ts   - The TS context obtained from TSCreate()
1377 - func - The function
1378 
1379   Calling sequence of func:
1380 . func (TS ts);
1381 
1382   Level: intermediate
1383 
1384 .keywords: TS, timestep
1385 @*/
1386 PetscErrorCode PETSCTS_DLLEXPORT TSSetPreStep(TS ts, PetscErrorCode (*func)(TS))
1387 {
1388   PetscFunctionBegin;
1389   PetscValidHeaderSpecific(ts, TS_COOKIE,1);
1390   ts->ops->prestep = func;
1391   PetscFunctionReturn(0);
1392 }
1393 
1394 #undef __FUNCT__
1395 #define __FUNCT__ "TSPreStep"
1396 /*@C
1397   TSPreStep - Runs the user-defined pre-step function.
1398 
1399   Collective on TS
1400 
1401   Input Parameters:
1402 . ts   - The TS context obtained from TSCreate()
1403 
1404   Notes:
1405   TSPreStep() is typically used within time stepping implementations,
1406   so most users would not generally call this routine themselves.
1407 
1408   Level: developer
1409 
1410 .keywords: TS, timestep
1411 @*/
1412 PetscErrorCode PETSCTS_DLLEXPORT TSPreStep(TS ts)
1413 {
1414   PetscErrorCode ierr;
1415 
1416   PetscFunctionBegin;
1417   PetscValidHeaderSpecific(ts,TS_COOKIE,1);
1418   PetscStackPush("TS PreStep function");
1419   CHKMEMQ;
1420   ierr = (*ts->ops->prestep)(ts);CHKERRQ(ierr);
1421   CHKMEMQ;
1422   PetscStackPop;
1423   PetscFunctionReturn(0);
1424 }
1425 
1426 #undef __FUNCT__
1427 #define __FUNCT__ "TSDefaultPreStep"
1428 /*@
1429   TSDefaultPreStep - The default pre-stepping function which does nothing.
1430 
1431   Collective on TS
1432 
1433   Input Parameters:
1434 . ts  - The TS context obtained from TSCreate()
1435 
1436   Level: developer
1437 
1438 .keywords: TS, timestep
1439 @*/
1440 PetscErrorCode PETSCTS_DLLEXPORT TSDefaultPreStep(TS ts)
1441 {
1442   PetscFunctionBegin;
1443   PetscFunctionReturn(0);
1444 }
1445 
1446 #undef __FUNCT__
1447 #define __FUNCT__ "TSSetPostStep"
1448 /*@C
1449   TSSetPostStep - Sets the general-purpose function
1450   called once at the end of each time step.
1451 
1452   Collective on TS
1453 
1454   Input Parameters:
1455 + ts   - The TS context obtained from TSCreate()
1456 - func - The function
1457 
1458   Calling sequence of func:
1459 . func (TS ts);
1460 
1461   Level: intermediate
1462 
1463 .keywords: TS, timestep
1464 @*/
1465 PetscErrorCode PETSCTS_DLLEXPORT TSSetPostStep(TS ts, PetscErrorCode (*func)(TS))
1466 {
1467   PetscFunctionBegin;
1468   PetscValidHeaderSpecific(ts, TS_COOKIE,1);
1469   ts->ops->poststep = func;
1470   PetscFunctionReturn(0);
1471 }
1472 
1473 #undef __FUNCT__
1474 #define __FUNCT__ "TSPostStep"
1475 /*@C
1476   TSPostStep - Runs the user-defined post-step function.
1477 
1478   Collective on TS
1479 
1480   Input Parameters:
1481 . ts   - The TS context obtained from TSCreate()
1482 
1483   Notes:
1484   TSPostStep() is typically used within time stepping implementations,
1485   so most users would not generally call this routine themselves.
1486 
1487   Level: developer
1488 
1489 .keywords: TS, timestep
1490 @*/
1491 PetscErrorCode PETSCTS_DLLEXPORT TSPostStep(TS ts)
1492 {
1493   PetscErrorCode ierr;
1494 
1495   PetscFunctionBegin;
1496   PetscValidHeaderSpecific(ts,TS_COOKIE,1);
1497   PetscStackPush("TS PostStep function");
1498   CHKMEMQ;
1499   ierr = (*ts->ops->poststep)(ts);CHKERRQ(ierr);
1500   CHKMEMQ;
1501   PetscStackPop;
1502   PetscFunctionReturn(0);
1503 }
1504 
1505 #undef __FUNCT__
1506 #define __FUNCT__ "TSDefaultPostStep"
1507 /*@
1508   TSDefaultPostStep - The default post-stepping function which does nothing.
1509 
1510   Collective on TS
1511 
1512   Input Parameters:
1513 . ts  - The TS context obtained from TSCreate()
1514 
1515   Level: developer
1516 
1517 .keywords: TS, timestep
1518 @*/
1519 PetscErrorCode PETSCTS_DLLEXPORT TSDefaultPostStep(TS ts)
1520 {
1521   PetscFunctionBegin;
1522   PetscFunctionReturn(0);
1523 }
1524 
1525 /* ------------ Routines to set performance monitoring options ----------- */
1526 
1527 #undef __FUNCT__
1528 #define __FUNCT__ "TSMonitorSet"
1529 /*@C
1530    TSMonitorSet - Sets an ADDITIONAL function that is to be used at every
1531    timestep to display the iteration's  progress.
1532 
1533    Collective on TS
1534 
1535    Input Parameters:
1536 +  ts - the TS context obtained from TSCreate()
1537 .  func - monitoring routine
1538 .  mctx - [optional] user-defined context for private data for the
1539              monitor routine (use PETSC_NULL if no context is desired)
1540 -  monitordestroy - [optional] routine that frees monitor context
1541           (may be PETSC_NULL)
1542 
1543    Calling sequence of func:
1544 $    int func(TS ts,PetscInt steps,PetscReal time,Vec x,void *mctx)
1545 
1546 +    ts - the TS context
1547 .    steps - iteration number
1548 .    time - current time
1549 .    x - current iterate
1550 -    mctx - [optional] monitoring context
1551 
1552    Notes:
1553    This routine adds an additional monitor to the list of monitors that
1554    already has been loaded.
1555 
1556    Fortran notes: Only a single monitor function can be set for each TS object
1557 
1558    Level: intermediate
1559 
1560 .keywords: TS, timestep, set, monitor
1561 
1562 .seealso: TSMonitorDefault(), TSMonitorCancel()
1563 @*/
1564 PetscErrorCode PETSCTS_DLLEXPORT TSMonitorSet(TS ts,PetscErrorCode (*monitor)(TS,PetscInt,PetscReal,Vec,void*),void *mctx,PetscErrorCode (*mdestroy)(void*))
1565 {
1566   PetscFunctionBegin;
1567   PetscValidHeaderSpecific(ts,TS_COOKIE,1);
1568   if (ts->numbermonitors >= MAXTSMONITORS) {
1569     SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Too many monitors set");
1570   }
1571   ts->monitor[ts->numbermonitors]           = monitor;
1572   ts->mdestroy[ts->numbermonitors]          = mdestroy;
1573   ts->monitorcontext[ts->numbermonitors++]  = (void*)mctx;
1574   PetscFunctionReturn(0);
1575 }
1576 
1577 #undef __FUNCT__
1578 #define __FUNCT__ "TSMonitorCancel"
1579 /*@C
1580    TSMonitorCancel - Clears all the monitors that have been set on a time-step object.
1581 
1582    Collective on TS
1583 
1584    Input Parameters:
1585 .  ts - the TS context obtained from TSCreate()
1586 
1587    Notes:
1588    There is no way to remove a single, specific monitor.
1589 
1590    Level: intermediate
1591 
1592 .keywords: TS, timestep, set, monitor
1593 
1594 .seealso: TSMonitorDefault(), TSMonitorSet()
1595 @*/
1596 PetscErrorCode PETSCTS_DLLEXPORT TSMonitorCancel(TS ts)
1597 {
1598   PetscErrorCode ierr;
1599   PetscInt       i;
1600 
1601   PetscFunctionBegin;
1602   PetscValidHeaderSpecific(ts,TS_COOKIE,1);
1603   for (i=0; i<ts->numbermonitors; i++) {
1604     if (ts->mdestroy[i]) {
1605       ierr = (*ts->mdestroy[i])(ts->monitorcontext[i]);CHKERRQ(ierr);
1606     }
1607   }
1608   ts->numbermonitors = 0;
1609   PetscFunctionReturn(0);
1610 }
1611 
1612 #undef __FUNCT__
1613 #define __FUNCT__ "TSMonitorDefault"
1614 /*@
1615    TSMonitorDefault - Sets the Default monitor
1616 
1617    Level: intermediate
1618 
1619 .keywords: TS, set, monitor
1620 
1621 .seealso: TSMonitorDefault(), TSMonitorSet()
1622 @*/
1623 PetscErrorCode TSMonitorDefault(TS ts,PetscInt step,PetscReal ptime,Vec v,void *ctx)
1624 {
1625   PetscErrorCode          ierr;
1626   PetscViewerASCIIMonitor viewer = (PetscViewerASCIIMonitor)ctx;
1627 
1628   PetscFunctionBegin;
1629   if (!ctx) {
1630     ierr = PetscViewerASCIIMonitorCreate(((PetscObject)ts)->comm,"stdout",0,&viewer);CHKERRQ(ierr);
1631   }
1632   ierr = PetscViewerASCIIMonitorPrintf(viewer,"timestep %D dt %G time %G\n",step,ts->time_step,ptime);CHKERRQ(ierr);
1633   if (!ctx) {
1634     ierr = PetscViewerASCIIMonitorDestroy(viewer);CHKERRQ(ierr);
1635   }
1636   PetscFunctionReturn(0);
1637 }
1638 
1639 #undef __FUNCT__
1640 #define __FUNCT__ "TSStep"
1641 /*@
1642    TSStep - Steps the requested number of timesteps.
1643 
1644    Collective on TS
1645 
1646    Input Parameter:
1647 .  ts - the TS context obtained from TSCreate()
1648 
1649    Output Parameters:
1650 +  steps - number of iterations until termination
1651 -  ptime - time until termination
1652 
1653    Level: beginner
1654 
1655 .keywords: TS, timestep, solve
1656 
1657 .seealso: TSCreate(), TSSetUp(), TSDestroy()
1658 @*/
1659 PetscErrorCode PETSCTS_DLLEXPORT TSStep(TS ts,PetscInt *steps,PetscReal *ptime)
1660 {
1661   PetscErrorCode ierr;
1662 
1663   PetscFunctionBegin;
1664   PetscValidHeaderSpecific(ts, TS_COOKIE,1);
1665   if (!ts->setupcalled) {
1666     ierr = TSSetUp(ts);CHKERRQ(ierr);
1667   }
1668 
1669   ierr = PetscLogEventBegin(TS_Step, ts, 0, 0, 0);CHKERRQ(ierr);
1670   ierr = (*ts->ops->step)(ts, steps, ptime);CHKERRQ(ierr);
1671   ierr = PetscLogEventEnd(TS_Step, ts, 0, 0, 0);CHKERRQ(ierr);
1672 
1673   if (!PetscPreLoadingOn) {
1674     ierr = TSViewFromOptions(ts,((PetscObject)ts)->name);CHKERRQ(ierr);
1675   }
1676   PetscFunctionReturn(0);
1677 }
1678 
1679 #undef __FUNCT__
1680 #define __FUNCT__ "TSSolve"
1681 /*@
1682    TSSolve - Steps the requested number of timesteps.
1683 
1684    Collective on TS
1685 
1686    Input Parameter:
1687 +  ts - the TS context obtained from TSCreate()
1688 -  x - the solution vector, or PETSC_NULL if it was set with TSSetSolution()
1689 
1690    Level: beginner
1691 
1692 .keywords: TS, timestep, solve
1693 
1694 .seealso: TSCreate(), TSSetSolution(), TSStep()
1695 @*/
1696 PetscErrorCode PETSCTS_DLLEXPORT TSSolve(TS ts, Vec x)
1697 {
1698   PetscInt       steps;
1699   PetscReal      ptime;
1700   PetscErrorCode ierr;
1701   PetscFunctionBegin;
1702   PetscValidHeaderSpecific(ts,TS_COOKIE,1);
1703   /* set solution vector if provided */
1704   if (x) { ierr = TSSetSolution(ts, x); CHKERRQ(ierr); }
1705   /* reset time step and iteration counters */
1706   ts->steps = 0; ts->linear_its = 0; ts->nonlinear_its = 0;
1707   /* steps the requested number of timesteps. */
1708   ierr = TSStep(ts, &steps, &ptime);CHKERRQ(ierr);
1709   PetscFunctionReturn(0);
1710 }
1711 
1712 #undef __FUNCT__
1713 #define __FUNCT__ "TSMonitor"
1714 /*
1715      Runs the user provided monitor routines, if they exists.
1716 */
1717 PetscErrorCode TSMonitor(TS ts,PetscInt step,PetscReal ptime,Vec x)
1718 {
1719   PetscErrorCode ierr;
1720   PetscInt i,n = ts->numbermonitors;
1721 
1722   PetscFunctionBegin;
1723   for (i=0; i<n; i++) {
1724     ierr = (*ts->monitor[i])(ts,step,ptime,x,ts->monitorcontext[i]);CHKERRQ(ierr);
1725   }
1726   PetscFunctionReturn(0);
1727 }
1728 
1729 /* ------------------------------------------------------------------------*/
1730 
1731 #undef __FUNCT__
1732 #define __FUNCT__ "TSMonitorLGCreate"
1733 /*@C
1734    TSMonitorLGCreate - Creates a line graph context for use with
1735    TS to monitor convergence of preconditioned residual norms.
1736 
1737    Collective on TS
1738 
1739    Input Parameters:
1740 +  host - the X display to open, or null for the local machine
1741 .  label - the title to put in the title bar
1742 .  x, y - the screen coordinates of the upper left coordinate of the window
1743 -  m, n - the screen width and height in pixels
1744 
1745    Output Parameter:
1746 .  draw - the drawing context
1747 
1748    Options Database Key:
1749 .  -ts_monitor_draw - automatically sets line graph monitor
1750 
1751    Notes:
1752    Use TSMonitorLGDestroy() to destroy this line graph, not PetscDrawLGDestroy().
1753 
1754    Level: intermediate
1755 
1756 .keywords: TS, monitor, line graph, residual, seealso
1757 
1758 .seealso: TSMonitorLGDestroy(), TSMonitorSet()
1759 
1760 @*/
1761 PetscErrorCode PETSCTS_DLLEXPORT TSMonitorLGCreate(const char host[],const char label[],int x,int y,int m,int n,PetscDrawLG *draw)
1762 {
1763   PetscDraw      win;
1764   PetscErrorCode ierr;
1765 
1766   PetscFunctionBegin;
1767   ierr = PetscDrawCreate(PETSC_COMM_SELF,host,label,x,y,m,n,&win);CHKERRQ(ierr);
1768   ierr = PetscDrawSetType(win,PETSC_DRAW_X);CHKERRQ(ierr);
1769   ierr = PetscDrawLGCreate(win,1,draw);CHKERRQ(ierr);
1770   ierr = PetscDrawLGIndicateDataPoints(*draw);CHKERRQ(ierr);
1771 
1772   ierr = PetscLogObjectParent(*draw,win);CHKERRQ(ierr);
1773   PetscFunctionReturn(0);
1774 }
1775 
1776 #undef __FUNCT__
1777 #define __FUNCT__ "TSMonitorLG"
1778 PetscErrorCode TSMonitorLG(TS ts,PetscInt n,PetscReal ptime,Vec v,void *monctx)
1779 {
1780   PetscDrawLG    lg = (PetscDrawLG) monctx;
1781   PetscReal      x,y = ptime;
1782   PetscErrorCode ierr;
1783 
1784   PetscFunctionBegin;
1785   if (!monctx) {
1786     MPI_Comm    comm;
1787     PetscViewer viewer;
1788 
1789     ierr   = PetscObjectGetComm((PetscObject)ts,&comm);CHKERRQ(ierr);
1790     viewer = PETSC_VIEWER_DRAW_(comm);
1791     ierr   = PetscViewerDrawGetDrawLG(viewer,0,&lg);CHKERRQ(ierr);
1792   }
1793 
1794   if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);}
1795   x = (PetscReal)n;
1796   ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr);
1797   if (n < 20 || (n % 5)) {
1798     ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr);
1799   }
1800   PetscFunctionReturn(0);
1801 }
1802 
1803 #undef __FUNCT__
1804 #define __FUNCT__ "TSMonitorLGDestroy"
1805 /*@C
1806    TSMonitorLGDestroy - Destroys a line graph context that was created
1807    with TSMonitorLGCreate().
1808 
1809    Collective on PetscDrawLG
1810 
1811    Input Parameter:
1812 .  draw - the drawing context
1813 
1814    Level: intermediate
1815 
1816 .keywords: TS, monitor, line graph, destroy
1817 
1818 .seealso: TSMonitorLGCreate(),  TSMonitorSet(), TSMonitorLG();
1819 @*/
1820 PetscErrorCode PETSCTS_DLLEXPORT TSMonitorLGDestroy(PetscDrawLG drawlg)
1821 {
1822   PetscDraw      draw;
1823   PetscErrorCode ierr;
1824 
1825   PetscFunctionBegin;
1826   ierr = PetscDrawLGGetDraw(drawlg,&draw);CHKERRQ(ierr);
1827   ierr = PetscDrawDestroy(draw);CHKERRQ(ierr);
1828   ierr = PetscDrawLGDestroy(drawlg);CHKERRQ(ierr);
1829   PetscFunctionReturn(0);
1830 }
1831 
1832 #undef __FUNCT__
1833 #define __FUNCT__ "TSGetTime"
1834 /*@
1835    TSGetTime - Gets the current time.
1836 
1837    Not Collective
1838 
1839    Input Parameter:
1840 .  ts - the TS context obtained from TSCreate()
1841 
1842    Output Parameter:
1843 .  t  - the current time
1844 
1845    Level: beginner
1846 
1847 .seealso: TSSetInitialTimeStep(), TSGetTimeStep()
1848 
1849 .keywords: TS, get, time
1850 @*/
1851 PetscErrorCode PETSCTS_DLLEXPORT TSGetTime(TS ts,PetscReal* t)
1852 {
1853   PetscFunctionBegin;
1854   PetscValidHeaderSpecific(ts,TS_COOKIE,1);
1855   PetscValidDoublePointer(t,2);
1856   *t = ts->ptime;
1857   PetscFunctionReturn(0);
1858 }
1859 
1860 #undef __FUNCT__
1861 #define __FUNCT__ "TSSetTime"
1862 /*@
1863    TSSetTime - Allows one to reset the time.
1864 
1865    Collective on TS
1866 
1867    Input Parameters:
1868 +  ts - the TS context obtained from TSCreate()
1869 -  time - the time
1870 
1871    Level: intermediate
1872 
1873 .seealso: TSGetTime(), TSSetDuration()
1874 
1875 .keywords: TS, set, time
1876 @*/
1877 PetscErrorCode PETSCTS_DLLEXPORT TSSetTime(TS ts, PetscReal t)
1878 {
1879   PetscFunctionBegin;
1880   PetscValidHeaderSpecific(ts,TS_COOKIE,1);
1881   ts->ptime = t;
1882   PetscFunctionReturn(0);
1883 }
1884 
1885 #undef __FUNCT__
1886 #define __FUNCT__ "TSSetOptionsPrefix"
1887 /*@C
1888    TSSetOptionsPrefix - Sets the prefix used for searching for all
1889    TS options in the database.
1890 
1891    Collective on TS
1892 
1893    Input Parameter:
1894 +  ts     - The TS context
1895 -  prefix - The prefix to prepend to all option names
1896 
1897    Notes:
1898    A hyphen (-) must NOT be given at the beginning of the prefix name.
1899    The first character of all runtime options is AUTOMATICALLY the
1900    hyphen.
1901 
1902    Level: advanced
1903 
1904 .keywords: TS, set, options, prefix, database
1905 
1906 .seealso: TSSetFromOptions()
1907 
1908 @*/
1909 PetscErrorCode PETSCTS_DLLEXPORT TSSetOptionsPrefix(TS ts,const char prefix[])
1910 {
1911   PetscErrorCode ierr;
1912 
1913   PetscFunctionBegin;
1914   PetscValidHeaderSpecific(ts,TS_COOKIE,1);
1915   ierr = PetscObjectSetOptionsPrefix((PetscObject)ts,prefix);CHKERRQ(ierr);
1916   switch(ts->problem_type) {
1917     case TS_NONLINEAR:
1918       if (ts->snes) {
1919         ierr = SNESSetOptionsPrefix(ts->snes,prefix);CHKERRQ(ierr);
1920       }
1921       break;
1922     case TS_LINEAR:
1923       if (ts->ksp) {
1924         ierr = KSPSetOptionsPrefix(ts->ksp,prefix);CHKERRQ(ierr);
1925       }
1926       break;
1927   }
1928   PetscFunctionReturn(0);
1929 }
1930 
1931 
1932 #undef __FUNCT__
1933 #define __FUNCT__ "TSAppendOptionsPrefix"
1934 /*@C
1935    TSAppendOptionsPrefix - Appends to the prefix used for searching for all
1936    TS options in the database.
1937 
1938    Collective on TS
1939 
1940    Input Parameter:
1941 +  ts     - The TS context
1942 -  prefix - The prefix to prepend to all option names
1943 
1944    Notes:
1945    A hyphen (-) must NOT be given at the beginning of the prefix name.
1946    The first character of all runtime options is AUTOMATICALLY the
1947    hyphen.
1948 
1949    Level: advanced
1950 
1951 .keywords: TS, append, options, prefix, database
1952 
1953 .seealso: TSGetOptionsPrefix()
1954 
1955 @*/
1956 PetscErrorCode PETSCTS_DLLEXPORT TSAppendOptionsPrefix(TS ts,const char prefix[])
1957 {
1958   PetscErrorCode ierr;
1959 
1960   PetscFunctionBegin;
1961   PetscValidHeaderSpecific(ts,TS_COOKIE,1);
1962   ierr = PetscObjectAppendOptionsPrefix((PetscObject)ts,prefix);CHKERRQ(ierr);
1963   switch(ts->problem_type) {
1964     case TS_NONLINEAR:
1965       if (ts->snes) {
1966         ierr = SNESAppendOptionsPrefix(ts->snes,prefix);CHKERRQ(ierr);
1967       }
1968       break;
1969     case TS_LINEAR:
1970       if (ts->ksp) {
1971         ierr = KSPAppendOptionsPrefix(ts->ksp,prefix);CHKERRQ(ierr);
1972       }
1973       break;
1974   }
1975   PetscFunctionReturn(0);
1976 }
1977 
1978 #undef __FUNCT__
1979 #define __FUNCT__ "TSGetOptionsPrefix"
1980 /*@C
1981    TSGetOptionsPrefix - Sets the prefix used for searching for all
1982    TS options in the database.
1983 
1984    Not Collective
1985 
1986    Input Parameter:
1987 .  ts - The TS context
1988 
1989    Output Parameter:
1990 .  prefix - A pointer to the prefix string used
1991 
1992    Notes: On the fortran side, the user should pass in a string 'prifix' of
1993    sufficient length to hold the prefix.
1994 
1995    Level: intermediate
1996 
1997 .keywords: TS, get, options, prefix, database
1998 
1999 .seealso: TSAppendOptionsPrefix()
2000 @*/
2001 PetscErrorCode PETSCTS_DLLEXPORT TSGetOptionsPrefix(TS ts,const char *prefix[])
2002 {
2003   PetscErrorCode ierr;
2004 
2005   PetscFunctionBegin;
2006   PetscValidHeaderSpecific(ts,TS_COOKIE,1);
2007   PetscValidPointer(prefix,2);
2008   ierr = PetscObjectGetOptionsPrefix((PetscObject)ts,prefix);CHKERRQ(ierr);
2009   PetscFunctionReturn(0);
2010 }
2011 
2012 #undef __FUNCT__
2013 #define __FUNCT__ "TSGetRHSJacobian"
2014 /*@C
2015    TSGetRHSJacobian - Returns the Jacobian J at the present timestep.
2016 
2017    Not Collective, but parallel objects are returned if TS is parallel
2018 
2019    Input Parameter:
2020 .  ts  - The TS context obtained from TSCreate()
2021 
2022    Output Parameters:
2023 +  J   - The Jacobian J of F, where U_t = F(U,t)
2024 .  M   - The preconditioner matrix, usually the same as J
2025 - ctx - User-defined context for Jacobian evaluation routine
2026 
2027    Notes: You can pass in PETSC_NULL for any return argument you do not need.
2028 
2029    Level: intermediate
2030 
2031 .seealso: TSGetTimeStep(), TSGetMatrices(), TSGetTime(), TSGetTimeStepNumber()
2032 
2033 .keywords: TS, timestep, get, matrix, Jacobian
2034 @*/
2035 PetscErrorCode PETSCTS_DLLEXPORT TSGetRHSJacobian(TS ts,Mat *J,Mat *M,void **ctx)
2036 {
2037   PetscFunctionBegin;
2038   if (J) *J = ts->Arhs;
2039   if (M) *M = ts->B;
2040   if (ctx) *ctx = ts->jacP;
2041   PetscFunctionReturn(0);
2042 }
2043 
2044 #undef __FUNCT__
2045 #define __FUNCT__ "TSMonitorSolution"
2046 /*@C
2047    TSMonitorSolution - Monitors progress of the TS solvers by calling
2048    VecView() for the solution at each timestep
2049 
2050    Collective on TS
2051 
2052    Input Parameters:
2053 +  ts - the TS context
2054 .  step - current time-step
2055 .  ptime - current time
2056 -  dummy - either a viewer or PETSC_NULL
2057 
2058    Level: intermediate
2059 
2060 .keywords: TS,  vector, monitor, view
2061 
2062 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView()
2063 @*/
2064 PetscErrorCode PETSCTS_DLLEXPORT TSMonitorSolution(TS ts,PetscInt step,PetscReal ptime,Vec x,void *dummy)
2065 {
2066   PetscErrorCode ierr;
2067   PetscViewer    viewer = (PetscViewer) dummy;
2068 
2069   PetscFunctionBegin;
2070   if (!dummy) {
2071     viewer = PETSC_VIEWER_DRAW_(((PetscObject)ts)->comm);
2072   }
2073   ierr = VecView(x,viewer);CHKERRQ(ierr);
2074   PetscFunctionReturn(0);
2075 }
2076 
2077 
2078 
2079