xref: /petsc/src/ts/interface/ts.c (revision 9596e0b48258fba4fca4f68feb5185896facfe69)
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 time stepping.
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__ "TSDefaultPreStep"
1396 /*@
1397   TSDefaultPreStep - The default pre-stepping function which does nothing.
1398 
1399   Collective on TS
1400 
1401   Input Parameters:
1402 . ts  - The TS context obtained from TSCreate()
1403 
1404   Level: developer
1405 
1406 .keywords: TS, timestep
1407 @*/
1408 PetscErrorCode PETSCTS_DLLEXPORT TSDefaultPreStep(TS ts)
1409 {
1410   PetscFunctionBegin;
1411   PetscFunctionReturn(0);
1412 }
1413 
1414 #undef __FUNCT__
1415 #define __FUNCT__ "TSSetPostStep"
1416 /*@C
1417   TSSetPostStep - Sets the general-purpose function
1418   called once at the end of time stepping.
1419 
1420   Collective on TS
1421 
1422   Input Parameters:
1423 + ts   - The TS context obtained from TSCreate()
1424 - func - The function
1425 
1426   Calling sequence of func:
1427 . func (TS ts);
1428 
1429   Level: intermediate
1430 
1431 .keywords: TS, timestep
1432 @*/
1433 PetscErrorCode PETSCTS_DLLEXPORT TSSetPostStep(TS ts, PetscErrorCode (*func)(TS))
1434 {
1435   PetscFunctionBegin;
1436   PetscValidHeaderSpecific(ts, TS_COOKIE,1);
1437   ts->ops->poststep = func;
1438   PetscFunctionReturn(0);
1439 }
1440 
1441 #undef __FUNCT__
1442 #define __FUNCT__ "TSDefaultPostStep"
1443 /*@
1444   TSDefaultPostStep - The default post-stepping function which does nothing.
1445 
1446   Collective on TS
1447 
1448   Input Parameters:
1449 . ts  - The TS context obtained from TSCreate()
1450 
1451   Level: developer
1452 
1453 .keywords: TS, timestep
1454 @*/
1455 PetscErrorCode PETSCTS_DLLEXPORT TSDefaultPostStep(TS ts)
1456 {
1457   PetscFunctionBegin;
1458   PetscFunctionReturn(0);
1459 }
1460 
1461 /* ------------ Routines to set performance monitoring options ----------- */
1462 
1463 #undef __FUNCT__
1464 #define __FUNCT__ "TSMonitorSet"
1465 /*@C
1466    TSMonitorSet - Sets an ADDITIONAL function that is to be used at every
1467    timestep to display the iteration's  progress.
1468 
1469    Collective on TS
1470 
1471    Input Parameters:
1472 +  ts - the TS context obtained from TSCreate()
1473 .  func - monitoring routine
1474 .  mctx - [optional] user-defined context for private data for the
1475              monitor routine (use PETSC_NULL if no context is desired)
1476 -  monitordestroy - [optional] routine that frees monitor context
1477           (may be PETSC_NULL)
1478 
1479    Calling sequence of func:
1480 $    int func(TS ts,PetscInt steps,PetscReal time,Vec x,void *mctx)
1481 
1482 +    ts - the TS context
1483 .    steps - iteration number
1484 .    time - current time
1485 .    x - current iterate
1486 -    mctx - [optional] monitoring context
1487 
1488    Notes:
1489    This routine adds an additional monitor to the list of monitors that
1490    already has been loaded.
1491 
1492    Fortran notes: Only a single monitor function can be set for each TS object
1493 
1494    Level: intermediate
1495 
1496 .keywords: TS, timestep, set, monitor
1497 
1498 .seealso: TSMonitorDefault(), TSMonitorCancel()
1499 @*/
1500 PetscErrorCode PETSCTS_DLLEXPORT TSMonitorSet(TS ts,PetscErrorCode (*monitor)(TS,PetscInt,PetscReal,Vec,void*),void *mctx,PetscErrorCode (*mdestroy)(void*))
1501 {
1502   PetscFunctionBegin;
1503   PetscValidHeaderSpecific(ts,TS_COOKIE,1);
1504   if (ts->numbermonitors >= MAXTSMONITORS) {
1505     SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Too many monitors set");
1506   }
1507   ts->monitor[ts->numbermonitors]           = monitor;
1508   ts->mdestroy[ts->numbermonitors]          = mdestroy;
1509   ts->monitorcontext[ts->numbermonitors++]  = (void*)mctx;
1510   PetscFunctionReturn(0);
1511 }
1512 
1513 #undef __FUNCT__
1514 #define __FUNCT__ "TSMonitorCancel"
1515 /*@C
1516    TSMonitorCancel - Clears all the monitors that have been set on a time-step object.
1517 
1518    Collective on TS
1519 
1520    Input Parameters:
1521 .  ts - the TS context obtained from TSCreate()
1522 
1523    Notes:
1524    There is no way to remove a single, specific monitor.
1525 
1526    Level: intermediate
1527 
1528 .keywords: TS, timestep, set, monitor
1529 
1530 .seealso: TSMonitorDefault(), TSMonitorSet()
1531 @*/
1532 PetscErrorCode PETSCTS_DLLEXPORT TSMonitorCancel(TS ts)
1533 {
1534   PetscErrorCode ierr;
1535   PetscInt       i;
1536 
1537   PetscFunctionBegin;
1538   PetscValidHeaderSpecific(ts,TS_COOKIE,1);
1539   for (i=0; i<ts->numbermonitors; i++) {
1540     if (ts->mdestroy[i]) {
1541       ierr = (*ts->mdestroy[i])(ts->monitorcontext[i]);CHKERRQ(ierr);
1542     }
1543   }
1544   ts->numbermonitors = 0;
1545   PetscFunctionReturn(0);
1546 }
1547 
1548 #undef __FUNCT__
1549 #define __FUNCT__ "TSMonitorDefault"
1550 /*@
1551    TSMonitorDefault - Sets the Default monitor
1552 
1553    Level: intermediate
1554 
1555 .keywords: TS, set, monitor
1556 
1557 .seealso: TSMonitorDefault(), TSMonitorSet()
1558 @*/
1559 PetscErrorCode TSMonitorDefault(TS ts,PetscInt step,PetscReal ptime,Vec v,void *ctx)
1560 {
1561   PetscErrorCode          ierr;
1562   PetscViewerASCIIMonitor viewer = (PetscViewerASCIIMonitor)ctx;
1563 
1564   PetscFunctionBegin;
1565   if (!ctx) {
1566     ierr = PetscViewerASCIIMonitorCreate(((PetscObject)ts)->comm,"stdout",0,&viewer);CHKERRQ(ierr);
1567   }
1568   ierr = PetscViewerASCIIMonitorPrintf(viewer,"timestep %D dt %G time %G\n",step,ts->time_step,ptime);CHKERRQ(ierr);
1569   if (!ctx) {
1570     ierr = PetscViewerASCIIMonitorDestroy(viewer);CHKERRQ(ierr);
1571   }
1572   PetscFunctionReturn(0);
1573 }
1574 
1575 #undef __FUNCT__
1576 #define __FUNCT__ "TSStep"
1577 /*@
1578    TSStep - Steps the requested number of timesteps.
1579 
1580    Collective on TS
1581 
1582    Input Parameter:
1583 .  ts - the TS context obtained from TSCreate()
1584 
1585    Output Parameters:
1586 +  steps - number of iterations until termination
1587 -  ptime - time until termination
1588 
1589    Level: beginner
1590 
1591 .keywords: TS, timestep, solve
1592 
1593 .seealso: TSCreate(), TSSetUp(), TSDestroy()
1594 @*/
1595 PetscErrorCode PETSCTS_DLLEXPORT TSStep(TS ts,PetscInt *steps,PetscReal *ptime)
1596 {
1597   PetscErrorCode ierr;
1598 
1599   PetscFunctionBegin;
1600   PetscValidHeaderSpecific(ts, TS_COOKIE,1);
1601   if (!ts->setupcalled) {
1602     ierr = TSSetUp(ts);CHKERRQ(ierr);
1603   }
1604 
1605   ierr = PetscLogEventBegin(TS_Step, ts, 0, 0, 0);CHKERRQ(ierr);
1606   ierr = (*ts->ops->prestep)(ts);CHKERRQ(ierr);
1607   ierr = (*ts->ops->step)(ts, steps, ptime);CHKERRQ(ierr);
1608   ierr = (*ts->ops->poststep)(ts);CHKERRQ(ierr);
1609   ierr = PetscLogEventEnd(TS_Step, ts, 0, 0, 0);CHKERRQ(ierr);
1610 
1611   if (!PetscPreLoadingOn) {
1612     ierr = TSViewFromOptions(ts,((PetscObject)ts)->name);CHKERRQ(ierr);
1613   }
1614   PetscFunctionReturn(0);
1615 }
1616 
1617 #undef __FUNCT__
1618 #define __FUNCT__ "TSSolve"
1619 /*@
1620    TSSolve - Steps the requested number of timesteps.
1621 
1622    Collective on TS
1623 
1624    Input Parameter:
1625 +  ts - the TS context obtained from TSCreate()
1626 -  x - the solution vector, or PETSC_NULL if it was set with TSSetSolution()
1627 
1628    Level: beginner
1629 
1630 .keywords: TS, timestep, solve
1631 
1632 .seealso: TSCreate(), TSSetSolution(), TSStep()
1633 @*/
1634 PetscErrorCode PETSCTS_DLLEXPORT TSSolve(TS ts, Vec x)
1635 {
1636   PetscInt       steps;
1637   PetscReal      ptime;
1638   PetscErrorCode ierr;
1639   PetscFunctionBegin;
1640   PetscValidHeaderSpecific(ts,TS_COOKIE,1);
1641   /* set solution vector if provided */
1642   if (x) { ierr = TSSetSolution(ts, x); CHKERRQ(ierr); }
1643   /* reset time step and iteration counters */
1644   ts->steps = 0; ts->linear_its = 0; ts->nonlinear_its = 0;
1645   /* steps the requested number of timesteps. */
1646   ierr = TSStep(ts, &steps, &ptime);CHKERRQ(ierr);
1647   PetscFunctionReturn(0);
1648 }
1649 
1650 #undef __FUNCT__
1651 #define __FUNCT__ "TSMonitor"
1652 /*
1653      Runs the user provided monitor routines, if they exists.
1654 */
1655 PetscErrorCode TSMonitor(TS ts,PetscInt step,PetscReal ptime,Vec x)
1656 {
1657   PetscErrorCode ierr;
1658   PetscInt i,n = ts->numbermonitors;
1659 
1660   PetscFunctionBegin;
1661   for (i=0; i<n; i++) {
1662     ierr = (*ts->monitor[i])(ts,step,ptime,x,ts->monitorcontext[i]);CHKERRQ(ierr);
1663   }
1664   PetscFunctionReturn(0);
1665 }
1666 
1667 /* ------------------------------------------------------------------------*/
1668 
1669 #undef __FUNCT__
1670 #define __FUNCT__ "TSMonitorLGCreate"
1671 /*@C
1672    TSMonitorLGCreate - Creates a line graph context for use with
1673    TS to monitor convergence of preconditioned residual norms.
1674 
1675    Collective on TS
1676 
1677    Input Parameters:
1678 +  host - the X display to open, or null for the local machine
1679 .  label - the title to put in the title bar
1680 .  x, y - the screen coordinates of the upper left coordinate of the window
1681 -  m, n - the screen width and height in pixels
1682 
1683    Output Parameter:
1684 .  draw - the drawing context
1685 
1686    Options Database Key:
1687 .  -ts_monitor_draw - automatically sets line graph monitor
1688 
1689    Notes:
1690    Use TSMonitorLGDestroy() to destroy this line graph, not PetscDrawLGDestroy().
1691 
1692    Level: intermediate
1693 
1694 .keywords: TS, monitor, line graph, residual, seealso
1695 
1696 .seealso: TSMonitorLGDestroy(), TSMonitorSet()
1697 
1698 @*/
1699 PetscErrorCode PETSCTS_DLLEXPORT TSMonitorLGCreate(const char host[],const char label[],int x,int y,int m,int n,PetscDrawLG *draw)
1700 {
1701   PetscDraw      win;
1702   PetscErrorCode ierr;
1703 
1704   PetscFunctionBegin;
1705   ierr = PetscDrawCreate(PETSC_COMM_SELF,host,label,x,y,m,n,&win);CHKERRQ(ierr);
1706   ierr = PetscDrawSetType(win,PETSC_DRAW_X);CHKERRQ(ierr);
1707   ierr = PetscDrawLGCreate(win,1,draw);CHKERRQ(ierr);
1708   ierr = PetscDrawLGIndicateDataPoints(*draw);CHKERRQ(ierr);
1709 
1710   ierr = PetscLogObjectParent(*draw,win);CHKERRQ(ierr);
1711   PetscFunctionReturn(0);
1712 }
1713 
1714 #undef __FUNCT__
1715 #define __FUNCT__ "TSMonitorLG"
1716 PetscErrorCode TSMonitorLG(TS ts,PetscInt n,PetscReal ptime,Vec v,void *monctx)
1717 {
1718   PetscDrawLG    lg = (PetscDrawLG) monctx;
1719   PetscReal      x,y = ptime;
1720   PetscErrorCode ierr;
1721 
1722   PetscFunctionBegin;
1723   if (!monctx) {
1724     MPI_Comm    comm;
1725     PetscViewer viewer;
1726 
1727     ierr   = PetscObjectGetComm((PetscObject)ts,&comm);CHKERRQ(ierr);
1728     viewer = PETSC_VIEWER_DRAW_(comm);
1729     ierr   = PetscViewerDrawGetDrawLG(viewer,0,&lg);CHKERRQ(ierr);
1730   }
1731 
1732   if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);}
1733   x = (PetscReal)n;
1734   ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr);
1735   if (n < 20 || (n % 5)) {
1736     ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr);
1737   }
1738   PetscFunctionReturn(0);
1739 }
1740 
1741 #undef __FUNCT__
1742 #define __FUNCT__ "TSMonitorLGDestroy"
1743 /*@C
1744    TSMonitorLGDestroy - Destroys a line graph context that was created
1745    with TSMonitorLGCreate().
1746 
1747    Collective on PetscDrawLG
1748 
1749    Input Parameter:
1750 .  draw - the drawing context
1751 
1752    Level: intermediate
1753 
1754 .keywords: TS, monitor, line graph, destroy
1755 
1756 .seealso: TSMonitorLGCreate(),  TSMonitorSet(), TSMonitorLG();
1757 @*/
1758 PetscErrorCode PETSCTS_DLLEXPORT TSMonitorLGDestroy(PetscDrawLG drawlg)
1759 {
1760   PetscDraw      draw;
1761   PetscErrorCode ierr;
1762 
1763   PetscFunctionBegin;
1764   ierr = PetscDrawLGGetDraw(drawlg,&draw);CHKERRQ(ierr);
1765   ierr = PetscDrawDestroy(draw);CHKERRQ(ierr);
1766   ierr = PetscDrawLGDestroy(drawlg);CHKERRQ(ierr);
1767   PetscFunctionReturn(0);
1768 }
1769 
1770 #undef __FUNCT__
1771 #define __FUNCT__ "TSGetTime"
1772 /*@
1773    TSGetTime - Gets the current time.
1774 
1775    Not Collective
1776 
1777    Input Parameter:
1778 .  ts - the TS context obtained from TSCreate()
1779 
1780    Output Parameter:
1781 .  t  - the current time
1782 
1783    Level: beginner
1784 
1785 .seealso: TSSetInitialTimeStep(), TSGetTimeStep()
1786 
1787 .keywords: TS, get, time
1788 @*/
1789 PetscErrorCode PETSCTS_DLLEXPORT TSGetTime(TS ts,PetscReal* t)
1790 {
1791   PetscFunctionBegin;
1792   PetscValidHeaderSpecific(ts,TS_COOKIE,1);
1793   PetscValidDoublePointer(t,2);
1794   *t = ts->ptime;
1795   PetscFunctionReturn(0);
1796 }
1797 
1798 #undef __FUNCT__
1799 #define __FUNCT__ "TSSetTime"
1800 /*@
1801    TSSetTime - Allows one to reset the time.
1802 
1803    Collective on TS
1804 
1805    Input Parameters:
1806 +  ts - the TS context obtained from TSCreate()
1807 -  time - the time
1808 
1809    Level: intermediate
1810 
1811 .seealso: TSGetTime(), TSSetDuration()
1812 
1813 .keywords: TS, set, time
1814 @*/
1815 PetscErrorCode PETSCTS_DLLEXPORT TSSetTime(TS ts, PetscReal t)
1816 {
1817   PetscFunctionBegin;
1818   PetscValidHeaderSpecific(ts,TS_COOKIE,1);
1819   ts->ptime = t;
1820   PetscFunctionReturn(0);
1821 }
1822 
1823 #undef __FUNCT__
1824 #define __FUNCT__ "TSSetOptionsPrefix"
1825 /*@C
1826    TSSetOptionsPrefix - Sets the prefix used for searching for all
1827    TS options in the database.
1828 
1829    Collective on TS
1830 
1831    Input Parameter:
1832 +  ts     - The TS context
1833 -  prefix - The prefix to prepend to all option names
1834 
1835    Notes:
1836    A hyphen (-) must NOT be given at the beginning of the prefix name.
1837    The first character of all runtime options is AUTOMATICALLY the
1838    hyphen.
1839 
1840    Level: advanced
1841 
1842 .keywords: TS, set, options, prefix, database
1843 
1844 .seealso: TSSetFromOptions()
1845 
1846 @*/
1847 PetscErrorCode PETSCTS_DLLEXPORT TSSetOptionsPrefix(TS ts,const char prefix[])
1848 {
1849   PetscErrorCode ierr;
1850 
1851   PetscFunctionBegin;
1852   PetscValidHeaderSpecific(ts,TS_COOKIE,1);
1853   ierr = PetscObjectSetOptionsPrefix((PetscObject)ts,prefix);CHKERRQ(ierr);
1854   switch(ts->problem_type) {
1855     case TS_NONLINEAR:
1856       if (ts->snes) {
1857         ierr = SNESSetOptionsPrefix(ts->snes,prefix);CHKERRQ(ierr);
1858       }
1859       break;
1860     case TS_LINEAR:
1861       if (ts->ksp) {
1862         ierr = KSPSetOptionsPrefix(ts->ksp,prefix);CHKERRQ(ierr);
1863       }
1864       break;
1865   }
1866   PetscFunctionReturn(0);
1867 }
1868 
1869 
1870 #undef __FUNCT__
1871 #define __FUNCT__ "TSAppendOptionsPrefix"
1872 /*@C
1873    TSAppendOptionsPrefix - Appends to the prefix used for searching for all
1874    TS options in the database.
1875 
1876    Collective on TS
1877 
1878    Input Parameter:
1879 +  ts     - The TS context
1880 -  prefix - The prefix to prepend to all option names
1881 
1882    Notes:
1883    A hyphen (-) must NOT be given at the beginning of the prefix name.
1884    The first character of all runtime options is AUTOMATICALLY the
1885    hyphen.
1886 
1887    Level: advanced
1888 
1889 .keywords: TS, append, options, prefix, database
1890 
1891 .seealso: TSGetOptionsPrefix()
1892 
1893 @*/
1894 PetscErrorCode PETSCTS_DLLEXPORT TSAppendOptionsPrefix(TS ts,const char prefix[])
1895 {
1896   PetscErrorCode ierr;
1897 
1898   PetscFunctionBegin;
1899   PetscValidHeaderSpecific(ts,TS_COOKIE,1);
1900   ierr = PetscObjectAppendOptionsPrefix((PetscObject)ts,prefix);CHKERRQ(ierr);
1901   switch(ts->problem_type) {
1902     case TS_NONLINEAR:
1903       if (ts->snes) {
1904         ierr = SNESAppendOptionsPrefix(ts->snes,prefix);CHKERRQ(ierr);
1905       }
1906       break;
1907     case TS_LINEAR:
1908       if (ts->ksp) {
1909         ierr = KSPAppendOptionsPrefix(ts->ksp,prefix);CHKERRQ(ierr);
1910       }
1911       break;
1912   }
1913   PetscFunctionReturn(0);
1914 }
1915 
1916 #undef __FUNCT__
1917 #define __FUNCT__ "TSGetOptionsPrefix"
1918 /*@C
1919    TSGetOptionsPrefix - Sets the prefix used for searching for all
1920    TS options in the database.
1921 
1922    Not Collective
1923 
1924    Input Parameter:
1925 .  ts - The TS context
1926 
1927    Output Parameter:
1928 .  prefix - A pointer to the prefix string used
1929 
1930    Notes: On the fortran side, the user should pass in a string 'prifix' of
1931    sufficient length to hold the prefix.
1932 
1933    Level: intermediate
1934 
1935 .keywords: TS, get, options, prefix, database
1936 
1937 .seealso: TSAppendOptionsPrefix()
1938 @*/
1939 PetscErrorCode PETSCTS_DLLEXPORT TSGetOptionsPrefix(TS ts,const char *prefix[])
1940 {
1941   PetscErrorCode ierr;
1942 
1943   PetscFunctionBegin;
1944   PetscValidHeaderSpecific(ts,TS_COOKIE,1);
1945   PetscValidPointer(prefix,2);
1946   ierr = PetscObjectGetOptionsPrefix((PetscObject)ts,prefix);CHKERRQ(ierr);
1947   PetscFunctionReturn(0);
1948 }
1949 
1950 #undef __FUNCT__
1951 #define __FUNCT__ "TSGetRHSJacobian"
1952 /*@C
1953    TSGetRHSJacobian - Returns the Jacobian J at the present timestep.
1954 
1955    Not Collective, but parallel objects are returned if TS is parallel
1956 
1957    Input Parameter:
1958 .  ts  - The TS context obtained from TSCreate()
1959 
1960    Output Parameters:
1961 +  J   - The Jacobian J of F, where U_t = F(U,t)
1962 .  M   - The preconditioner matrix, usually the same as J
1963 - ctx - User-defined context for Jacobian evaluation routine
1964 
1965    Notes: You can pass in PETSC_NULL for any return argument you do not need.
1966 
1967    Level: intermediate
1968 
1969 .seealso: TSGetTimeStep(), TSGetMatrices(), TSGetTime(), TSGetTimeStepNumber()
1970 
1971 .keywords: TS, timestep, get, matrix, Jacobian
1972 @*/
1973 PetscErrorCode PETSCTS_DLLEXPORT TSGetRHSJacobian(TS ts,Mat *J,Mat *M,void **ctx)
1974 {
1975   PetscFunctionBegin;
1976   if (J) *J = ts->Arhs;
1977   if (M) *M = ts->B;
1978   if (ctx) *ctx = ts->jacP;
1979   PetscFunctionReturn(0);
1980 }
1981 
1982 #undef __FUNCT__
1983 #define __FUNCT__ "TSMonitorSolution"
1984 /*@C
1985    TSMonitorSolution - Monitors progress of the TS solvers by calling
1986    VecView() for the solution at each timestep
1987 
1988    Collective on TS
1989 
1990    Input Parameters:
1991 +  ts - the TS context
1992 .  step - current time-step
1993 .  ptime - current time
1994 -  dummy - either a viewer or PETSC_NULL
1995 
1996    Level: intermediate
1997 
1998 .keywords: TS,  vector, monitor, view
1999 
2000 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView()
2001 @*/
2002 PetscErrorCode PETSCTS_DLLEXPORT TSMonitorSolution(TS ts,PetscInt step,PetscReal ptime,Vec x,void *dummy)
2003 {
2004   PetscErrorCode ierr;
2005   PetscViewer    viewer = (PetscViewer) dummy;
2006 
2007   PetscFunctionBegin;
2008   if (!dummy) {
2009     viewer = PETSC_VIEWER_DRAW_(((PetscObject)ts)->comm);
2010   }
2011   ierr = VecView(x,viewer);CHKERRQ(ierr);
2012   PetscFunctionReturn(0);
2013 }
2014 
2015 
2016 
2017