xref: /petsc/src/ts/interface/ts.c (revision e32f2f54e699d0aa6e733466c00da7e34666fe5e)
1 #define PETSCTS_DLL
2 
3 #include "private/tsimpl.h"        /*I "petscts.h"  I*/
4 
5 /* Logging support */
6 PetscClassId PETSCTS_DLLEXPORT TS_CLASSID;
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, TSCN, TSRK, TSTHETA, TSGL, TSSSP
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_CLASSID,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_COMM_SELF,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_CLASSID,1);
234   PetscValidHeaderSpecific(X,VEC_CLASSID,3);
235   PetscCheckSameComm(ts,1,X,3);
236   if (ts->problem_type != TS_NONLINEAR) {
237     SETERRQ(PETSC_COMM_SELF,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_CLASSID,4);
248     PetscValidHeaderSpecific(*B,MAT_CLASSID,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_CLASSID,1);
294   PetscValidHeaderSpecific(x,VEC_CLASSID,3);
295   PetscValidHeaderSpecific(y,VEC_CLASSID,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_CLASSID,1);
352   PetscValidHeaderSpecific(X,VEC_CLASSID,3);
353   PetscValidHeaderSpecific(Xdot,VEC_CLASSID,4);
354   PetscValidHeaderSpecific(Y,VEC_CLASSID,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         /* Note: flg is not being used.
370            For it to be useful, we'd have to cache it and then apply it in TSComputeIJacobian.
371         */
372         PetscStackPush("TS user right-hand-side matrix function");
373         ierr = (*ts->ops->rhsmatrix)(ts,t,&ts->Arhs,&ts->B,&flg,ts->jacP);CHKERRQ(ierr);
374         PetscStackPop;
375       }
376       ierr = MatMult(ts->Arhs,X,Y);CHKERRQ(ierr);
377     }
378 
379     /* Convert to implicit form: F(X,Xdot) = Alhs * Xdot - Frhs(X) */
380     if (ts->Alhs) {
381       if (ts->ops->lhsmatrix) {
382         MatStructure flg;
383         PetscStackPush("TS user left-hand-side matrix function");
384         ierr = (*ts->ops->lhsmatrix)(ts,t,&ts->Alhs,PETSC_NULL,&flg,ts->jacP);CHKERRQ(ierr);
385         PetscStackPop;
386       }
387       ierr = VecScale(Y,-1.);CHKERRQ(ierr);
388       ierr = MatMultAdd(ts->Alhs,Xdot,Y,Y);CHKERRQ(ierr);
389     } else {
390       ierr = VecAYPX(Y,-1,Xdot);CHKERRQ(ierr);
391     }
392   }
393   ierr = PetscLogEventEnd(TS_FunctionEval,ts,X,Xdot,Y);CHKERRQ(ierr);
394   PetscFunctionReturn(0);
395 }
396 
397 #undef __FUNCT__
398 #define __FUNCT__ "TSComputeIJacobian"
399 /*@
400    TSComputeIJacobian - Evaluates the Jacobian of the DAE
401 
402    Collective on TS and Vec
403 
404    Input
405       Input Parameters:
406 +  ts - the TS context
407 .  t - current timestep
408 .  X - state vector
409 .  Xdot - time derivative of state vector
410 -  shift - shift to apply, see note below
411 
412    Output Parameters:
413 +  A - Jacobian matrix
414 .  B - optional preconditioning matrix
415 -  flag - flag indicating matrix structure
416 
417    Notes:
418    If F(t,X,Xdot)=0 is the DAE, the required Jacobian is
419 
420    dF/dX + shift*dF/dXdot
421 
422    Most users should not need to explicitly call this routine, as it
423    is used internally within the nonlinear solvers.
424 
425    TSComputeIJacobian() is valid only for TS_NONLINEAR
426 
427    Level: developer
428 
429 .keywords: TS, compute, Jacobian, matrix
430 
431 .seealso:  TSSetIJacobian()
432 @*/
433 PetscErrorCode PETSCTS_DLLEXPORT TSComputeIJacobian(TS ts,PetscReal t,Vec X,Vec Xdot,PetscReal shift,Mat *A,Mat *B,MatStructure *flg)
434 {
435   PetscErrorCode ierr;
436 
437   PetscFunctionBegin;
438   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
439   PetscValidHeaderSpecific(X,VEC_CLASSID,3);
440   PetscValidHeaderSpecific(Xdot,VEC_CLASSID,4);
441   PetscValidPointer(A,6);
442   PetscValidHeaderSpecific(*A,MAT_CLASSID,6);
443   PetscValidPointer(B,7);
444   PetscValidHeaderSpecific(*B,MAT_CLASSID,7);
445   PetscValidPointer(flg,8);
446 
447   *flg = SAME_NONZERO_PATTERN;  /* In case it we're solving a linear problem in which case it wouldn't get initialized below. */
448   ierr = PetscLogEventBegin(TS_JacobianEval,ts,X,*A,*B);CHKERRQ(ierr);
449   if (ts->ops->ijacobian) {
450     PetscStackPush("TS user implicit Jacobian");
451     ierr = (*ts->ops->ijacobian)(ts,t,X,Xdot,shift,A,B,flg,ts->jacP);CHKERRQ(ierr);
452     PetscStackPop;
453   } else {
454     if (ts->ops->rhsjacobian) {
455       PetscStackPush("TS user right-hand-side Jacobian");
456       ierr = (*ts->ops->rhsjacobian)(ts,t,X,A,B,flg,ts->jacP);CHKERRQ(ierr);
457       PetscStackPop;
458     } else {
459       ierr = MatAssemblyBegin(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
460       ierr = MatAssemblyEnd(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
461       if (*A != *B) {
462         ierr = MatAssemblyBegin(*B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
463         ierr = MatAssemblyEnd(*B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
464       }
465     }
466 
467     /* Convert to implicit form */
468     /* inefficient because these operations will normally traverse all matrix elements twice */
469     ierr = MatScale(*A,-1);CHKERRQ(ierr);
470     if (ts->Alhs) {
471       ierr = MatAXPY(*A,shift,ts->Alhs,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr);
472     } else {
473       ierr = MatShift(*A,shift);CHKERRQ(ierr);
474     }
475     if (*A != *B) {
476       ierr = MatScale(*B,-1);CHKERRQ(ierr);
477       ierr = MatShift(*B,shift);CHKERRQ(ierr);
478     }
479   }
480   ierr = PetscLogEventEnd(TS_JacobianEval,ts,X,*A,*B);CHKERRQ(ierr);
481   PetscFunctionReturn(0);
482 }
483 
484 #undef __FUNCT__
485 #define __FUNCT__ "TSSetRHSFunction"
486 /*@C
487     TSSetRHSFunction - Sets the routine for evaluating the function,
488     F(t,u), where U_t = F(t,u).
489 
490     Collective on TS
491 
492     Input Parameters:
493 +   ts - the TS context obtained from TSCreate()
494 .   f - routine for evaluating the right-hand-side function
495 -   ctx - [optional] user-defined context for private data for the
496           function evaluation routine (may be PETSC_NULL)
497 
498     Calling sequence of func:
499 $     func (TS ts,PetscReal t,Vec u,Vec F,void *ctx);
500 
501 +   t - current timestep
502 .   u - input vector
503 .   F - function vector
504 -   ctx - [optional] user-defined function context
505 
506     Important:
507     The user MUST call either this routine or TSSetMatrices().
508 
509     Level: beginner
510 
511 .keywords: TS, timestep, set, right-hand-side, function
512 
513 .seealso: TSSetMatrices()
514 @*/
515 PetscErrorCode PETSCTS_DLLEXPORT TSSetRHSFunction(TS ts,PetscErrorCode (*f)(TS,PetscReal,Vec,Vec,void*),void *ctx)
516 {
517   PetscFunctionBegin;
518 
519   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
520   if (ts->problem_type == TS_LINEAR) {
521     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Cannot set function for linear problem");
522   }
523   ts->ops->rhsfunction = f;
524   ts->funP             = ctx;
525   PetscFunctionReturn(0);
526 }
527 
528 #undef __FUNCT__
529 #define __FUNCT__ "TSSetMatrices"
530 /*@C
531    TSSetMatrices - Sets the functions to compute the matrices Alhs and Arhs,
532    where Alhs(t) U_t = Arhs(t) U.
533 
534    Collective on TS
535 
536    Input Parameters:
537 +  ts   - the TS context obtained from TSCreate()
538 .  Arhs - matrix
539 .  frhs - the matrix evaluation routine for Arhs; use PETSC_NULL (PETSC_NULL_FUNCTION in fortran)
540           if Arhs is not a function of t.
541 .  Alhs - matrix or PETSC_NULL if Alhs is an indentity matrix.
542 .  flhs - the matrix evaluation routine for Alhs; use PETSC_NULL (PETSC_NULL_FUNCTION in fortran)
543           if Alhs is not a function of t.
544 .  flag - flag indicating information about the matrix structure of Arhs and Alhs.
545           The available options are
546             SAME_NONZERO_PATTERN - Alhs has the same nonzero structure as Arhs
547             DIFFERENT_NONZERO_PATTERN - Alhs has different nonzero structure as Arhs
548 -  ctx  - [optional] user-defined context for private data for the
549           matrix evaluation routine (may be PETSC_NULL)
550 
551    Calling sequence of func:
552 $     func(TS ts,PetscReal t,Mat *A,Mat *B,PetscInt *flag,void *ctx);
553 
554 +  t - current timestep
555 .  A - matrix A, where U_t = A(t) U
556 .  B - preconditioner matrix, usually the same as A
557 .  flag - flag indicating information about the preconditioner matrix
558           structure (same as flag in KSPSetOperators())
559 -  ctx - [optional] user-defined context for matrix evaluation routine
560 
561    Notes:
562    The routine func() takes Mat* as the matrix arguments rather than Mat.
563    This allows the matrix evaluation routine to replace Arhs or Alhs with a
564    completely new new matrix structure (not just different matrix elements)
565    when appropriate, for instance, if the nonzero structure is changing
566    throughout the global iterations.
567 
568    Important:
569    The user MUST call either this routine or TSSetRHSFunction().
570 
571    Level: beginner
572 
573 .keywords: TS, timestep, set, matrix
574 
575 .seealso: TSSetRHSFunction()
576 @*/
577 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)
578 {
579   PetscFunctionBegin;
580   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
581   if (Arhs){
582     PetscValidHeaderSpecific(Arhs,MAT_CLASSID,2);
583     PetscCheckSameComm(ts,1,Arhs,2);
584     ts->Arhs           = Arhs;
585     ts->ops->rhsmatrix = frhs;
586   }
587   if (Alhs){
588     PetscValidHeaderSpecific(Alhs,MAT_CLASSID,4);
589     PetscCheckSameComm(ts,1,Alhs,4);
590     ts->Alhs           = Alhs;
591     ts->ops->lhsmatrix = flhs;
592   }
593 
594   ts->jacP           = ctx;
595   ts->matflg         = flag;
596   PetscFunctionReturn(0);
597 }
598 
599 #undef __FUNCT__
600 #define __FUNCT__ "TSGetMatrices"
601 /*@C
602    TSGetMatrices - Returns the matrices Arhs and Alhs at the present timestep,
603    where Alhs(t) U_t = Arhs(t) U.
604 
605    Not Collective, but parallel objects are returned if TS is parallel
606 
607    Input Parameter:
608 .  ts  - The TS context obtained from TSCreate()
609 
610    Output Parameters:
611 +  Arhs - The right-hand side matrix
612 .  Alhs - The left-hand side matrix
613 -  ctx - User-defined context for matrix evaluation routine
614 
615    Notes: You can pass in PETSC_NULL for any return argument you do not need.
616 
617    Level: intermediate
618 
619 .seealso: TSSetMatrices(), TSGetTimeStep(), TSGetTime(), TSGetTimeStepNumber(), TSGetRHSJacobian()
620 
621 .keywords: TS, timestep, get, matrix
622 
623 @*/
624 PetscErrorCode PETSCTS_DLLEXPORT TSGetMatrices(TS ts,Mat *Arhs,Mat *Alhs,void **ctx)
625 {
626   PetscFunctionBegin;
627   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
628   if (Arhs) *Arhs = ts->Arhs;
629   if (Alhs) *Alhs = ts->Alhs;
630   if (ctx)  *ctx = ts->jacP;
631   PetscFunctionReturn(0);
632 }
633 
634 #undef __FUNCT__
635 #define __FUNCT__ "TSSetRHSJacobian"
636 /*@C
637    TSSetRHSJacobian - Sets the function to compute the Jacobian of F,
638    where U_t = F(U,t), as well as the location to store the matrix.
639    Use TSSetMatrices() for linear problems.
640 
641    Collective on TS
642 
643    Input Parameters:
644 +  ts  - the TS context obtained from TSCreate()
645 .  A   - Jacobian matrix
646 .  B   - preconditioner matrix (usually same as A)
647 .  f   - the Jacobian evaluation routine
648 -  ctx - [optional] user-defined context for private data for the
649          Jacobian evaluation routine (may be PETSC_NULL)
650 
651    Calling sequence of func:
652 $     func (TS ts,PetscReal t,Vec u,Mat *A,Mat *B,MatStructure *flag,void *ctx);
653 
654 +  t - current timestep
655 .  u - input vector
656 .  A - matrix A, where U_t = A(t)u
657 .  B - preconditioner matrix, usually the same as A
658 .  flag - flag indicating information about the preconditioner matrix
659           structure (same as flag in KSPSetOperators())
660 -  ctx - [optional] user-defined context for matrix evaluation routine
661 
662    Notes:
663    See KSPSetOperators() for important information about setting the flag
664    output parameter in the routine func().  Be sure to read this information!
665 
666    The routine func() takes Mat * as the matrix arguments rather than Mat.
667    This allows the matrix evaluation routine to replace A and/or B with a
668    completely new matrix structure (not just different matrix elements)
669    when appropriate, for instance, if the nonzero structure is changing
670    throughout the global iterations.
671 
672    Level: beginner
673 
674 .keywords: TS, timestep, set, right-hand-side, Jacobian
675 
676 .seealso: TSDefaultComputeJacobianColor(),
677           SNESDefaultComputeJacobianColor(), TSSetRHSFunction(), TSSetMatrices()
678 
679 @*/
680 PetscErrorCode PETSCTS_DLLEXPORT TSSetRHSJacobian(TS ts,Mat A,Mat B,PetscErrorCode (*f)(TS,PetscReal,Vec,Mat*,Mat*,MatStructure*,void*),void *ctx)
681 {
682   PetscFunctionBegin;
683   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
684   PetscValidHeaderSpecific(A,MAT_CLASSID,2);
685   PetscValidHeaderSpecific(B,MAT_CLASSID,3);
686   PetscCheckSameComm(ts,1,A,2);
687   PetscCheckSameComm(ts,1,B,3);
688   if (ts->problem_type != TS_NONLINEAR) {
689     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Not for linear problems; use TSSetMatrices()");
690   }
691 
692   ts->ops->rhsjacobian = f;
693   ts->jacP             = ctx;
694   ts->Arhs             = A;
695   ts->B                = B;
696   PetscFunctionReturn(0);
697 }
698 
699 
700 #undef __FUNCT__
701 #define __FUNCT__ "TSSetIFunction"
702 /*@C
703    TSSetIFunction - Set the function to compute F(t,U,U_t) where F = 0 is the DAE to be solved.
704 
705    Collective on TS
706 
707    Input Parameters:
708 +  ts  - the TS context obtained from TSCreate()
709 .  f   - the function evaluation routine
710 -  ctx - user-defined context for private data for the function evaluation routine (may be PETSC_NULL)
711 
712    Calling sequence of f:
713 $  f(TS ts,PetscReal t,Vec u,Vec u_t,Vec F,ctx);
714 
715 +  t   - time at step/stage being solved
716 .  u   - state vector
717 .  u_t - time derivative of state vector
718 .  F   - function vector
719 -  ctx - [optional] user-defined context for matrix evaluation routine
720 
721    Important:
722    The user MUST call either this routine, TSSetRHSFunction(), or TSSetMatrices().  This routine must be used when not solving an ODE.
723 
724    Level: beginner
725 
726 .keywords: TS, timestep, set, DAE, Jacobian
727 
728 .seealso: TSSetMatrices(), TSSetRHSFunction(), TSSetIJacobian()
729 @*/
730 PetscErrorCode PETSCTS_DLLEXPORT TSSetIFunction(TS ts,TSIFunction f,void *ctx)
731 {
732 
733   PetscFunctionBegin;
734   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
735   ts->ops->ifunction = f;
736   ts->funP           = ctx;
737   PetscFunctionReturn(0);
738 }
739 
740 #undef __FUNCT__
741 #define __FUNCT__ "TSSetIJacobian"
742 /*@C
743    TSSetIJacobian - Set the function to compute the Jacobian of
744    G(U) = F(t,U,U0+a*U) where F(t,U,U_t) = 0 is the DAE to be solved.
745 
746    Collective on TS
747 
748    Input Parameters:
749 +  ts  - the TS context obtained from TSCreate()
750 .  A   - Jacobian matrix
751 .  B   - preconditioning matrix for A (may be same as A)
752 .  f   - the Jacobian evaluation routine
753 -  ctx - user-defined context for private data for the Jacobian evaluation routine (may be PETSC_NULL)
754 
755    Calling sequence of f:
756 $  f(TS ts,PetscReal t,Vec u,Vec u_t,PetscReal a,Mat *A,Mat *B,MatStructure *flag,void *ctx);
757 
758 +  t    - time at step/stage being solved
759 .  u    - state vector
760 .  u_t  - time derivative of state vector
761 .  a    - shift
762 .  A    - Jacobian of G(U) = F(t,U,U0+a*U), equivalent to dF/dU + a*dF/dU_t
763 .  B    - preconditioning matrix for A, may be same as A
764 .  flag - flag indicating information about the preconditioner matrix
765           structure (same as flag in KSPSetOperators())
766 -  ctx  - [optional] user-defined context for matrix evaluation routine
767 
768    Notes:
769    The matrices A and B are exactly the matrices that are used by SNES for the nonlinear solve.
770 
771    Level: beginner
772 
773 .keywords: TS, timestep, DAE, Jacobian
774 
775 .seealso: TSSetIFunction(), TSSetRHSJacobian()
776 
777 @*/
778 PetscErrorCode PETSCTS_DLLEXPORT TSSetIJacobian(TS ts,Mat A,Mat B,TSIJacobian f,void *ctx)
779 {
780   PetscErrorCode ierr;
781 
782   PetscFunctionBegin;
783   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
784   if (A) PetscValidHeaderSpecific(A,MAT_CLASSID,2);
785   if (B) PetscValidHeaderSpecific(B,MAT_CLASSID,3);
786   if (A) PetscCheckSameComm(ts,1,A,2);
787   if (B) PetscCheckSameComm(ts,1,B,3);
788   if (f)   ts->ops->ijacobian = f;
789   if (ctx) ts->jacP             = ctx;
790   if (A) {
791     ierr = PetscObjectReference((PetscObject)A);CHKERRQ(ierr);
792     if (ts->A) {ierr = MatDestroy(ts->A);CHKERRQ(ierr);}
793     ts->A = A;
794   }
795 #if 0
796   /* The sane and consistent alternative */
797   if (B) {
798     ierr = PetscObjectReference((PetscObject)B);CHKERRQ(ierr);
799     if (ts->B) {ierr = MatDestroy(ts->B);CHKERRQ(ierr);}
800     ts->B = B;
801   }
802 #else
803   /* Don't reference B because TSDestroy() doesn't destroy it.  These ownership semantics are awkward and inconsistent. */
804   if (B) ts->B = B;
805 #endif
806   PetscFunctionReturn(0);
807 }
808 
809 #undef __FUNCT__
810 #define __FUNCT__ "TSView"
811 /*@C
812     TSView - Prints the TS data structure.
813 
814     Collective on TS
815 
816     Input Parameters:
817 +   ts - the TS context obtained from TSCreate()
818 -   viewer - visualization context
819 
820     Options Database Key:
821 .   -ts_view - calls TSView() at end of TSStep()
822 
823     Notes:
824     The available visualization contexts include
825 +     PETSC_VIEWER_STDOUT_SELF - standard output (default)
826 -     PETSC_VIEWER_STDOUT_WORLD - synchronized standard
827          output where only the first processor opens
828          the file.  All other processors send their
829          data to the first processor to print.
830 
831     The user can open an alternative visualization context with
832     PetscViewerASCIIOpen() - output to a specified file.
833 
834     Level: beginner
835 
836 .keywords: TS, timestep, view
837 
838 .seealso: PetscViewerASCIIOpen()
839 @*/
840 PetscErrorCode PETSCTS_DLLEXPORT TSView(TS ts,PetscViewer viewer)
841 {
842   PetscErrorCode ierr;
843   const TSType   type;
844   PetscTruth     iascii,isstring;
845 
846   PetscFunctionBegin;
847   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
848   if (!viewer) {
849     ierr = PetscViewerASCIIGetStdout(((PetscObject)ts)->comm,&viewer);CHKERRQ(ierr);
850   }
851   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2);
852   PetscCheckSameComm(ts,1,viewer,2);
853 
854   ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&iascii);CHKERRQ(ierr);
855   ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_STRING,&isstring);CHKERRQ(ierr);
856   if (iascii) {
857     ierr = PetscViewerASCIIPrintf(viewer,"TS Object:\n");CHKERRQ(ierr);
858     ierr = TSGetType(ts,&type);CHKERRQ(ierr);
859     if (type) {
860       ierr = PetscViewerASCIIPrintf(viewer,"  type: %s\n",type);CHKERRQ(ierr);
861     } else {
862       ierr = PetscViewerASCIIPrintf(viewer,"  type: not yet set\n");CHKERRQ(ierr);
863     }
864     if (ts->ops->view) {
865       ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
866       ierr = (*ts->ops->view)(ts,viewer);CHKERRQ(ierr);
867       ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
868     }
869     ierr = PetscViewerASCIIPrintf(viewer,"  maximum steps=%D\n",ts->max_steps);CHKERRQ(ierr);
870     ierr = PetscViewerASCIIPrintf(viewer,"  maximum time=%G\n",ts->max_time);CHKERRQ(ierr);
871     if (ts->problem_type == TS_NONLINEAR) {
872       ierr = PetscViewerASCIIPrintf(viewer,"  total number of nonlinear solver iterations=%D\n",ts->nonlinear_its);CHKERRQ(ierr);
873     }
874     ierr = PetscViewerASCIIPrintf(viewer,"  total number of linear solver iterations=%D\n",ts->linear_its);CHKERRQ(ierr);
875   } else if (isstring) {
876     ierr = TSGetType(ts,&type);CHKERRQ(ierr);
877     ierr = PetscViewerStringSPrintf(viewer," %-7.7s",type);CHKERRQ(ierr);
878   }
879   ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
880   if (ts->ksp) {ierr = KSPView(ts->ksp,viewer);CHKERRQ(ierr);}
881   if (ts->snes) {ierr = SNESView(ts->snes,viewer);CHKERRQ(ierr);}
882   ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
883   PetscFunctionReturn(0);
884 }
885 
886 
887 #undef __FUNCT__
888 #define __FUNCT__ "TSSetApplicationContext"
889 /*@C
890    TSSetApplicationContext - Sets an optional user-defined context for
891    the timesteppers.
892 
893    Collective on TS
894 
895    Input Parameters:
896 +  ts - the TS context obtained from TSCreate()
897 -  usrP - optional user context
898 
899    Level: intermediate
900 
901 .keywords: TS, timestep, set, application, context
902 
903 .seealso: TSGetApplicationContext()
904 @*/
905 PetscErrorCode PETSCTS_DLLEXPORT TSSetApplicationContext(TS ts,void *usrP)
906 {
907   PetscFunctionBegin;
908   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
909   ts->user = usrP;
910   PetscFunctionReturn(0);
911 }
912 
913 #undef __FUNCT__
914 #define __FUNCT__ "TSGetApplicationContext"
915 /*@C
916     TSGetApplicationContext - Gets the user-defined context for the
917     timestepper.
918 
919     Not Collective
920 
921     Input Parameter:
922 .   ts - the TS context obtained from TSCreate()
923 
924     Output Parameter:
925 .   usrP - user context
926 
927     Level: intermediate
928 
929 .keywords: TS, timestep, get, application, context
930 
931 .seealso: TSSetApplicationContext()
932 @*/
933 PetscErrorCode PETSCTS_DLLEXPORT TSGetApplicationContext(TS ts,void **usrP)
934 {
935   PetscFunctionBegin;
936   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
937   *usrP = ts->user;
938   PetscFunctionReturn(0);
939 }
940 
941 #undef __FUNCT__
942 #define __FUNCT__ "TSGetTimeStepNumber"
943 /*@
944    TSGetTimeStepNumber - Gets the current number of timesteps.
945 
946    Not Collective
947 
948    Input Parameter:
949 .  ts - the TS context obtained from TSCreate()
950 
951    Output Parameter:
952 .  iter - number steps so far
953 
954    Level: intermediate
955 
956 .keywords: TS, timestep, get, iteration, number
957 @*/
958 PetscErrorCode PETSCTS_DLLEXPORT TSGetTimeStepNumber(TS ts,PetscInt* iter)
959 {
960   PetscFunctionBegin;
961   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
962   PetscValidIntPointer(iter,2);
963   *iter = ts->steps;
964   PetscFunctionReturn(0);
965 }
966 
967 #undef __FUNCT__
968 #define __FUNCT__ "TSSetInitialTimeStep"
969 /*@
970    TSSetInitialTimeStep - Sets the initial timestep to be used,
971    as well as the initial time.
972 
973    Collective on TS
974 
975    Input Parameters:
976 +  ts - the TS context obtained from TSCreate()
977 .  initial_time - the initial time
978 -  time_step - the size of the timestep
979 
980    Level: intermediate
981 
982 .seealso: TSSetTimeStep(), TSGetTimeStep()
983 
984 .keywords: TS, set, initial, timestep
985 @*/
986 PetscErrorCode PETSCTS_DLLEXPORT TSSetInitialTimeStep(TS ts,PetscReal initial_time,PetscReal time_step)
987 {
988   PetscFunctionBegin;
989   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
990   ts->time_step         = time_step;
991   ts->initial_time_step = time_step;
992   ts->ptime             = initial_time;
993   PetscFunctionReturn(0);
994 }
995 
996 #undef __FUNCT__
997 #define __FUNCT__ "TSSetTimeStep"
998 /*@
999    TSSetTimeStep - Allows one to reset the timestep at any time,
1000    useful for simple pseudo-timestepping codes.
1001 
1002    Collective on TS
1003 
1004    Input Parameters:
1005 +  ts - the TS context obtained from TSCreate()
1006 -  time_step - the size of the timestep
1007 
1008    Level: intermediate
1009 
1010 .seealso: TSSetInitialTimeStep(), TSGetTimeStep()
1011 
1012 .keywords: TS, set, timestep
1013 @*/
1014 PetscErrorCode PETSCTS_DLLEXPORT TSSetTimeStep(TS ts,PetscReal time_step)
1015 {
1016   PetscFunctionBegin;
1017   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
1018   ts->time_step = time_step;
1019   PetscFunctionReturn(0);
1020 }
1021 
1022 #undef __FUNCT__
1023 #define __FUNCT__ "TSGetTimeStep"
1024 /*@
1025    TSGetTimeStep - Gets the current timestep size.
1026 
1027    Not Collective
1028 
1029    Input Parameter:
1030 .  ts - the TS context obtained from TSCreate()
1031 
1032    Output Parameter:
1033 .  dt - the current timestep size
1034 
1035    Level: intermediate
1036 
1037 .seealso: TSSetInitialTimeStep(), TSGetTimeStep()
1038 
1039 .keywords: TS, get, timestep
1040 @*/
1041 PetscErrorCode PETSCTS_DLLEXPORT TSGetTimeStep(TS ts,PetscReal* dt)
1042 {
1043   PetscFunctionBegin;
1044   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
1045   PetscValidDoublePointer(dt,2);
1046   *dt = ts->time_step;
1047   PetscFunctionReturn(0);
1048 }
1049 
1050 #undef __FUNCT__
1051 #define __FUNCT__ "TSGetSolution"
1052 /*@
1053    TSGetSolution - Returns the solution at the present timestep. It
1054    is valid to call this routine inside the function that you are evaluating
1055    in order to move to the new timestep. This vector not changed until
1056    the solution at the next timestep has been calculated.
1057 
1058    Not Collective, but Vec returned is parallel if TS is parallel
1059 
1060    Input Parameter:
1061 .  ts - the TS context obtained from TSCreate()
1062 
1063    Output Parameter:
1064 .  v - the vector containing the solution
1065 
1066    Level: intermediate
1067 
1068 .seealso: TSGetTimeStep()
1069 
1070 .keywords: TS, timestep, get, solution
1071 @*/
1072 PetscErrorCode PETSCTS_DLLEXPORT TSGetSolution(TS ts,Vec *v)
1073 {
1074   PetscFunctionBegin;
1075   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
1076   PetscValidPointer(v,2);
1077   *v = ts->vec_sol_always;
1078   PetscFunctionReturn(0);
1079 }
1080 
1081 /* ----- Routines to initialize and destroy a timestepper ---- */
1082 #undef __FUNCT__
1083 #define __FUNCT__ "TSSetProblemType"
1084 /*@
1085   TSSetProblemType - Sets the type of problem to be solved.
1086 
1087   Not collective
1088 
1089   Input Parameters:
1090 + ts   - The TS
1091 - type - One of TS_LINEAR, TS_NONLINEAR where these types refer to problems of the forms
1092 .vb
1093          U_t = A U
1094          U_t = A(t) U
1095          U_t = F(t,U)
1096 .ve
1097 
1098    Level: beginner
1099 
1100 .keywords: TS, problem type
1101 .seealso: TSSetUp(), TSProblemType, TS
1102 @*/
1103 PetscErrorCode PETSCTS_DLLEXPORT TSSetProblemType(TS ts, TSProblemType type)
1104 {
1105   PetscFunctionBegin;
1106   PetscValidHeaderSpecific(ts, TS_CLASSID,1);
1107   ts->problem_type = type;
1108   PetscFunctionReturn(0);
1109 }
1110 
1111 #undef __FUNCT__
1112 #define __FUNCT__ "TSGetProblemType"
1113 /*@C
1114   TSGetProblemType - Gets the type of problem to be solved.
1115 
1116   Not collective
1117 
1118   Input Parameter:
1119 . ts   - The TS
1120 
1121   Output Parameter:
1122 . type - One of TS_LINEAR, TS_NONLINEAR where these types refer to problems of the forms
1123 .vb
1124          U_t = A U
1125          U_t = A(t) U
1126          U_t = F(t,U)
1127 .ve
1128 
1129    Level: beginner
1130 
1131 .keywords: TS, problem type
1132 .seealso: TSSetUp(), TSProblemType, TS
1133 @*/
1134 PetscErrorCode PETSCTS_DLLEXPORT TSGetProblemType(TS ts, TSProblemType *type)
1135 {
1136   PetscFunctionBegin;
1137   PetscValidHeaderSpecific(ts, TS_CLASSID,1);
1138   PetscValidIntPointer(type,2);
1139   *type = ts->problem_type;
1140   PetscFunctionReturn(0);
1141 }
1142 
1143 #undef __FUNCT__
1144 #define __FUNCT__ "TSSetUp"
1145 /*@
1146    TSSetUp - Sets up the internal data structures for the later use
1147    of a timestepper.
1148 
1149    Collective on TS
1150 
1151    Input Parameter:
1152 .  ts - the TS context obtained from TSCreate()
1153 
1154    Notes:
1155    For basic use of the TS solvers the user need not explicitly call
1156    TSSetUp(), since these actions will automatically occur during
1157    the call to TSStep().  However, if one wishes to control this
1158    phase separately, TSSetUp() should be called after TSCreate()
1159    and optional routines of the form TSSetXXX(), but before TSStep().
1160 
1161    Level: advanced
1162 
1163 .keywords: TS, timestep, setup
1164 
1165 .seealso: TSCreate(), TSStep(), TSDestroy()
1166 @*/
1167 PetscErrorCode PETSCTS_DLLEXPORT TSSetUp(TS ts)
1168 {
1169   PetscErrorCode ierr;
1170 
1171   PetscFunctionBegin;
1172   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
1173   if (!ts->vec_sol) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Must call TSSetSolution() first");
1174   if (!((PetscObject)ts)->type_name) {
1175     ierr = TSSetType(ts,TSEULER);CHKERRQ(ierr);
1176   }
1177   ierr = (*ts->ops->setup)(ts);CHKERRQ(ierr);
1178   ts->setupcalled = 1;
1179   PetscFunctionReturn(0);
1180 }
1181 
1182 #undef __FUNCT__
1183 #define __FUNCT__ "TSDestroy"
1184 /*@
1185    TSDestroy - Destroys the timestepper context that was created
1186    with TSCreate().
1187 
1188    Collective on TS
1189 
1190    Input Parameter:
1191 .  ts - the TS context obtained from TSCreate()
1192 
1193    Level: beginner
1194 
1195 .keywords: TS, timestepper, destroy
1196 
1197 .seealso: TSCreate(), TSSetUp(), TSSolve()
1198 @*/
1199 PetscErrorCode PETSCTS_DLLEXPORT TSDestroy(TS ts)
1200 {
1201   PetscErrorCode ierr;
1202 
1203   PetscFunctionBegin;
1204   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
1205   if (--((PetscObject)ts)->refct > 0) PetscFunctionReturn(0);
1206 
1207   /* if memory was published with AMS then destroy it */
1208   ierr = PetscObjectDepublish(ts);CHKERRQ(ierr);
1209 
1210   if (ts->dm) {ierr = DMDestroy(ts->dm);CHKERRQ(ierr);}
1211   if (ts->A) {ierr = MatDestroy(ts->A);CHKERRQ(ierr)}
1212   if (ts->ksp) {ierr = KSPDestroy(ts->ksp);CHKERRQ(ierr);}
1213   if (ts->snes) {ierr = SNESDestroy(ts->snes);CHKERRQ(ierr);}
1214   if (ts->ops->destroy) {ierr = (*(ts)->ops->destroy)(ts);CHKERRQ(ierr);}
1215   ierr = TSMonitorCancel(ts);CHKERRQ(ierr);
1216   ierr = PetscHeaderDestroy(ts);CHKERRQ(ierr);
1217   PetscFunctionReturn(0);
1218 }
1219 
1220 #undef __FUNCT__
1221 #define __FUNCT__ "TSGetSNES"
1222 /*@
1223    TSGetSNES - Returns the SNES (nonlinear solver) associated with
1224    a TS (timestepper) context. Valid only for nonlinear problems.
1225 
1226    Not Collective, but SNES is parallel if TS is parallel
1227 
1228    Input Parameter:
1229 .  ts - the TS context obtained from TSCreate()
1230 
1231    Output Parameter:
1232 .  snes - the nonlinear solver context
1233 
1234    Notes:
1235    The user can then directly manipulate the SNES context to set various
1236    options, etc.  Likewise, the user can then extract and manipulate the
1237    KSP, KSP, and PC contexts as well.
1238 
1239    TSGetSNES() does not work for integrators that do not use SNES; in
1240    this case TSGetSNES() returns PETSC_NULL in snes.
1241 
1242    Level: beginner
1243 
1244 .keywords: timestep, get, SNES
1245 @*/
1246 PetscErrorCode PETSCTS_DLLEXPORT TSGetSNES(TS ts,SNES *snes)
1247 {
1248   PetscFunctionBegin;
1249   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
1250   PetscValidPointer(snes,2);
1251   if (((PetscObject)ts)->type_name == PETSC_NULL)
1252     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"SNES is not created yet. Call TSSetType() first");
1253   if (ts->problem_type == TS_LINEAR) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Nonlinear only; use TSGetKSP()");
1254   *snes = ts->snes;
1255   PetscFunctionReturn(0);
1256 }
1257 
1258 #undef __FUNCT__
1259 #define __FUNCT__ "TSGetKSP"
1260 /*@
1261    TSGetKSP - Returns the KSP (linear solver) associated with
1262    a TS (timestepper) context.
1263 
1264    Not Collective, but KSP is parallel if TS is parallel
1265 
1266    Input Parameter:
1267 .  ts - the TS context obtained from TSCreate()
1268 
1269    Output Parameter:
1270 .  ksp - the nonlinear solver context
1271 
1272    Notes:
1273    The user can then directly manipulate the KSP context to set various
1274    options, etc.  Likewise, the user can then extract and manipulate the
1275    KSP and PC contexts as well.
1276 
1277    TSGetKSP() does not work for integrators that do not use KSP;
1278    in this case TSGetKSP() returns PETSC_NULL in ksp.
1279 
1280    Level: beginner
1281 
1282 .keywords: timestep, get, KSP
1283 @*/
1284 PetscErrorCode PETSCTS_DLLEXPORT TSGetKSP(TS ts,KSP *ksp)
1285 {
1286   PetscFunctionBegin;
1287   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
1288   PetscValidPointer(ksp,2);
1289   if (((PetscObject)ts)->type_name == PETSC_NULL)
1290     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"KSP is not created yet. Call TSSetType() first");
1291   if (ts->problem_type != TS_LINEAR) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Linear only; use TSGetSNES()");
1292   *ksp = ts->ksp;
1293   PetscFunctionReturn(0);
1294 }
1295 
1296 /* ----------- Routines to set solver parameters ---------- */
1297 
1298 #undef __FUNCT__
1299 #define __FUNCT__ "TSGetDuration"
1300 /*@
1301    TSGetDuration - Gets the maximum number of timesteps to use and
1302    maximum time for iteration.
1303 
1304    Collective on TS
1305 
1306    Input Parameters:
1307 +  ts       - the TS context obtained from TSCreate()
1308 .  maxsteps - maximum number of iterations to use, or PETSC_NULL
1309 -  maxtime  - final time to iterate to, or PETSC_NULL
1310 
1311    Level: intermediate
1312 
1313 .keywords: TS, timestep, get, maximum, iterations, time
1314 @*/
1315 PetscErrorCode PETSCTS_DLLEXPORT TSGetDuration(TS ts, PetscInt *maxsteps, PetscReal *maxtime)
1316 {
1317   PetscFunctionBegin;
1318   PetscValidHeaderSpecific(ts, TS_CLASSID,1);
1319   if (maxsteps) {
1320     PetscValidIntPointer(maxsteps,2);
1321     *maxsteps = ts->max_steps;
1322   }
1323   if (maxtime ) {
1324     PetscValidScalarPointer(maxtime,3);
1325     *maxtime  = ts->max_time;
1326   }
1327   PetscFunctionReturn(0);
1328 }
1329 
1330 #undef __FUNCT__
1331 #define __FUNCT__ "TSSetDuration"
1332 /*@
1333    TSSetDuration - Sets the maximum number of timesteps to use and
1334    maximum time for iteration.
1335 
1336    Collective on TS
1337 
1338    Input Parameters:
1339 +  ts - the TS context obtained from TSCreate()
1340 .  maxsteps - maximum number of iterations to use
1341 -  maxtime - final time to iterate to
1342 
1343    Options Database Keys:
1344 .  -ts_max_steps <maxsteps> - Sets maxsteps
1345 .  -ts_max_time <maxtime> - Sets maxtime
1346 
1347    Notes:
1348    The default maximum number of iterations is 5000. Default time is 5.0
1349 
1350    Level: intermediate
1351 
1352 .keywords: TS, timestep, set, maximum, iterations
1353 @*/
1354 PetscErrorCode PETSCTS_DLLEXPORT TSSetDuration(TS ts,PetscInt maxsteps,PetscReal maxtime)
1355 {
1356   PetscFunctionBegin;
1357   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
1358   ts->max_steps = maxsteps;
1359   ts->max_time  = maxtime;
1360   PetscFunctionReturn(0);
1361 }
1362 
1363 #undef __FUNCT__
1364 #define __FUNCT__ "TSSetSolution"
1365 /*@
1366    TSSetSolution - Sets the initial solution vector
1367    for use by the TS routines.
1368 
1369    Collective on TS and Vec
1370 
1371    Input Parameters:
1372 +  ts - the TS context obtained from TSCreate()
1373 -  x - the solution vector
1374 
1375    Level: beginner
1376 
1377 .keywords: TS, timestep, set, solution, initial conditions
1378 @*/
1379 PetscErrorCode PETSCTS_DLLEXPORT TSSetSolution(TS ts,Vec x)
1380 {
1381   PetscFunctionBegin;
1382   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
1383   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
1384   ts->vec_sol        = ts->vec_sol_always = x;
1385   PetscFunctionReturn(0);
1386 }
1387 
1388 #undef __FUNCT__
1389 #define __FUNCT__ "TSSetPreStep"
1390 /*@C
1391   TSSetPreStep - Sets the general-purpose function
1392   called once at the beginning of each time step.
1393 
1394   Collective on TS
1395 
1396   Input Parameters:
1397 + ts   - The TS context obtained from TSCreate()
1398 - func - The function
1399 
1400   Calling sequence of func:
1401 . func (TS ts);
1402 
1403   Level: intermediate
1404 
1405 .keywords: TS, timestep
1406 @*/
1407 PetscErrorCode PETSCTS_DLLEXPORT TSSetPreStep(TS ts, PetscErrorCode (*func)(TS))
1408 {
1409   PetscFunctionBegin;
1410   PetscValidHeaderSpecific(ts, TS_CLASSID,1);
1411   ts->ops->prestep = func;
1412   PetscFunctionReturn(0);
1413 }
1414 
1415 #undef __FUNCT__
1416 #define __FUNCT__ "TSPreStep"
1417 /*@C
1418   TSPreStep - Runs the user-defined pre-step function.
1419 
1420   Collective on TS
1421 
1422   Input Parameters:
1423 . ts   - The TS context obtained from TSCreate()
1424 
1425   Notes:
1426   TSPreStep() is typically used within time stepping implementations,
1427   so most users would not generally call this routine themselves.
1428 
1429   Level: developer
1430 
1431 .keywords: TS, timestep
1432 @*/
1433 PetscErrorCode PETSCTS_DLLEXPORT TSPreStep(TS ts)
1434 {
1435   PetscErrorCode ierr;
1436 
1437   PetscFunctionBegin;
1438   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
1439   if (ts->ops->prestep) {
1440     PetscStackPush("TS PreStep function");
1441     CHKMEMQ;
1442     ierr = (*ts->ops->prestep)(ts);CHKERRQ(ierr);
1443     CHKMEMQ;
1444     PetscStackPop;
1445   }
1446   PetscFunctionReturn(0);
1447 }
1448 
1449 #undef __FUNCT__
1450 #define __FUNCT__ "TSDefaultPreStep"
1451 /*@
1452   TSDefaultPreStep - The default pre-stepping function which does nothing.
1453 
1454   Collective on TS
1455 
1456   Input Parameters:
1457 . ts  - The TS context obtained from TSCreate()
1458 
1459   Level: developer
1460 
1461 .keywords: TS, timestep
1462 @*/
1463 PetscErrorCode PETSCTS_DLLEXPORT TSDefaultPreStep(TS ts)
1464 {
1465   PetscFunctionBegin;
1466   PetscFunctionReturn(0);
1467 }
1468 
1469 #undef __FUNCT__
1470 #define __FUNCT__ "TSSetPostStep"
1471 /*@C
1472   TSSetPostStep - Sets the general-purpose function
1473   called once at the end of each time step.
1474 
1475   Collective on TS
1476 
1477   Input Parameters:
1478 + ts   - The TS context obtained from TSCreate()
1479 - func - The function
1480 
1481   Calling sequence of func:
1482 . func (TS ts);
1483 
1484   Level: intermediate
1485 
1486 .keywords: TS, timestep
1487 @*/
1488 PetscErrorCode PETSCTS_DLLEXPORT TSSetPostStep(TS ts, PetscErrorCode (*func)(TS))
1489 {
1490   PetscFunctionBegin;
1491   PetscValidHeaderSpecific(ts, TS_CLASSID,1);
1492   ts->ops->poststep = func;
1493   PetscFunctionReturn(0);
1494 }
1495 
1496 #undef __FUNCT__
1497 #define __FUNCT__ "TSPostStep"
1498 /*@C
1499   TSPostStep - Runs the user-defined post-step function.
1500 
1501   Collective on TS
1502 
1503   Input Parameters:
1504 . ts   - The TS context obtained from TSCreate()
1505 
1506   Notes:
1507   TSPostStep() is typically used within time stepping implementations,
1508   so most users would not generally call this routine themselves.
1509 
1510   Level: developer
1511 
1512 .keywords: TS, timestep
1513 @*/
1514 PetscErrorCode PETSCTS_DLLEXPORT TSPostStep(TS ts)
1515 {
1516   PetscErrorCode ierr;
1517 
1518   PetscFunctionBegin;
1519   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
1520   if (ts->ops->poststep) {
1521     PetscStackPush("TS PostStep function");
1522     CHKMEMQ;
1523     ierr = (*ts->ops->poststep)(ts);CHKERRQ(ierr);
1524     CHKMEMQ;
1525     PetscStackPop;
1526   }
1527   PetscFunctionReturn(0);
1528 }
1529 
1530 #undef __FUNCT__
1531 #define __FUNCT__ "TSDefaultPostStep"
1532 /*@
1533   TSDefaultPostStep - The default post-stepping function which does nothing.
1534 
1535   Collective on TS
1536 
1537   Input Parameters:
1538 . ts  - The TS context obtained from TSCreate()
1539 
1540   Level: developer
1541 
1542 .keywords: TS, timestep
1543 @*/
1544 PetscErrorCode PETSCTS_DLLEXPORT TSDefaultPostStep(TS ts)
1545 {
1546   PetscFunctionBegin;
1547   PetscFunctionReturn(0);
1548 }
1549 
1550 /* ------------ Routines to set performance monitoring options ----------- */
1551 
1552 #undef __FUNCT__
1553 #define __FUNCT__ "TSMonitorSet"
1554 /*@C
1555    TSMonitorSet - Sets an ADDITIONAL function that is to be used at every
1556    timestep to display the iteration's  progress.
1557 
1558    Collective on TS
1559 
1560    Input Parameters:
1561 +  ts - the TS context obtained from TSCreate()
1562 .  func - monitoring routine
1563 .  mctx - [optional] user-defined context for private data for the
1564              monitor routine (use PETSC_NULL if no context is desired)
1565 -  monitordestroy - [optional] routine that frees monitor context
1566           (may be PETSC_NULL)
1567 
1568    Calling sequence of func:
1569 $    int func(TS ts,PetscInt steps,PetscReal time,Vec x,void *mctx)
1570 
1571 +    ts - the TS context
1572 .    steps - iteration number
1573 .    time - current time
1574 .    x - current iterate
1575 -    mctx - [optional] monitoring context
1576 
1577    Notes:
1578    This routine adds an additional monitor to the list of monitors that
1579    already has been loaded.
1580 
1581    Fortran notes: Only a single monitor function can be set for each TS object
1582 
1583    Level: intermediate
1584 
1585 .keywords: TS, timestep, set, monitor
1586 
1587 .seealso: TSMonitorDefault(), TSMonitorCancel()
1588 @*/
1589 PetscErrorCode PETSCTS_DLLEXPORT TSMonitorSet(TS ts,PetscErrorCode (*monitor)(TS,PetscInt,PetscReal,Vec,void*),void *mctx,PetscErrorCode (*mdestroy)(void*))
1590 {
1591   PetscFunctionBegin;
1592   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
1593   if (ts->numbermonitors >= MAXTSMONITORS) {
1594     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Too many monitors set");
1595   }
1596   ts->monitor[ts->numbermonitors]           = monitor;
1597   ts->mdestroy[ts->numbermonitors]          = mdestroy;
1598   ts->monitorcontext[ts->numbermonitors++]  = (void*)mctx;
1599   PetscFunctionReturn(0);
1600 }
1601 
1602 #undef __FUNCT__
1603 #define __FUNCT__ "TSMonitorCancel"
1604 /*@C
1605    TSMonitorCancel - Clears all the monitors that have been set on a time-step object.
1606 
1607    Collective on TS
1608 
1609    Input Parameters:
1610 .  ts - the TS context obtained from TSCreate()
1611 
1612    Notes:
1613    There is no way to remove a single, specific monitor.
1614 
1615    Level: intermediate
1616 
1617 .keywords: TS, timestep, set, monitor
1618 
1619 .seealso: TSMonitorDefault(), TSMonitorSet()
1620 @*/
1621 PetscErrorCode PETSCTS_DLLEXPORT TSMonitorCancel(TS ts)
1622 {
1623   PetscErrorCode ierr;
1624   PetscInt       i;
1625 
1626   PetscFunctionBegin;
1627   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
1628   for (i=0; i<ts->numbermonitors; i++) {
1629     if (ts->mdestroy[i]) {
1630       ierr = (*ts->mdestroy[i])(ts->monitorcontext[i]);CHKERRQ(ierr);
1631     }
1632   }
1633   ts->numbermonitors = 0;
1634   PetscFunctionReturn(0);
1635 }
1636 
1637 #undef __FUNCT__
1638 #define __FUNCT__ "TSMonitorDefault"
1639 /*@
1640    TSMonitorDefault - Sets the Default monitor
1641 
1642    Level: intermediate
1643 
1644 .keywords: TS, set, monitor
1645 
1646 .seealso: TSMonitorDefault(), TSMonitorSet()
1647 @*/
1648 PetscErrorCode TSMonitorDefault(TS ts,PetscInt step,PetscReal ptime,Vec v,void *ctx)
1649 {
1650   PetscErrorCode          ierr;
1651   PetscViewerASCIIMonitor viewer = (PetscViewerASCIIMonitor)ctx;
1652 
1653   PetscFunctionBegin;
1654   if (!ctx) {
1655     ierr = PetscViewerASCIIMonitorCreate(((PetscObject)ts)->comm,"stdout",0,&viewer);CHKERRQ(ierr);
1656   }
1657   ierr = PetscViewerASCIIMonitorPrintf(viewer,"%D TS dt %G time %G\n",step,ts->time_step,ptime);CHKERRQ(ierr);
1658   if (!ctx) {
1659     ierr = PetscViewerASCIIMonitorDestroy(viewer);CHKERRQ(ierr);
1660   }
1661   PetscFunctionReturn(0);
1662 }
1663 
1664 #undef __FUNCT__
1665 #define __FUNCT__ "TSStep"
1666 /*@
1667    TSStep - Steps the requested number of timesteps.
1668 
1669    Collective on TS
1670 
1671    Input Parameter:
1672 .  ts - the TS context obtained from TSCreate()
1673 
1674    Output Parameters:
1675 +  steps - number of iterations until termination
1676 -  ptime - time until termination
1677 
1678    Level: beginner
1679 
1680 .keywords: TS, timestep, solve
1681 
1682 .seealso: TSCreate(), TSSetUp(), TSDestroy()
1683 @*/
1684 PetscErrorCode PETSCTS_DLLEXPORT TSStep(TS ts,PetscInt *steps,PetscReal *ptime)
1685 {
1686   PetscErrorCode ierr;
1687 
1688   PetscFunctionBegin;
1689   PetscValidHeaderSpecific(ts, TS_CLASSID,1);
1690   if (!ts->setupcalled) {
1691     ierr = TSSetUp(ts);CHKERRQ(ierr);
1692   }
1693 
1694   ierr = PetscLogEventBegin(TS_Step, ts, 0, 0, 0);CHKERRQ(ierr);
1695   ierr = (*ts->ops->step)(ts, steps, ptime);CHKERRQ(ierr);
1696   ierr = PetscLogEventEnd(TS_Step, ts, 0, 0, 0);CHKERRQ(ierr);
1697 
1698   if (!PetscPreLoadingOn) {
1699     ierr = TSViewFromOptions(ts,((PetscObject)ts)->name);CHKERRQ(ierr);
1700   }
1701   PetscFunctionReturn(0);
1702 }
1703 
1704 #undef __FUNCT__
1705 #define __FUNCT__ "TSSolve"
1706 /*@
1707    TSSolve - Steps the requested number of timesteps.
1708 
1709    Collective on TS
1710 
1711    Input Parameter:
1712 +  ts - the TS context obtained from TSCreate()
1713 -  x - the solution vector, or PETSC_NULL if it was set with TSSetSolution()
1714 
1715    Level: beginner
1716 
1717 .keywords: TS, timestep, solve
1718 
1719 .seealso: TSCreate(), TSSetSolution(), TSStep()
1720 @*/
1721 PetscErrorCode PETSCTS_DLLEXPORT TSSolve(TS ts, Vec x)
1722 {
1723   PetscInt       steps;
1724   PetscReal      ptime;
1725   PetscErrorCode ierr;
1726 
1727   PetscFunctionBegin;
1728   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
1729   /* set solution vector if provided */
1730   if (x) { ierr = TSSetSolution(ts, x); CHKERRQ(ierr); }
1731   /* reset time step and iteration counters */
1732   ts->steps = 0; ts->linear_its = 0; ts->nonlinear_its = 0;
1733   /* steps the requested number of timesteps. */
1734   ierr = TSStep(ts, &steps, &ptime);CHKERRQ(ierr);
1735   PetscFunctionReturn(0);
1736 }
1737 
1738 #undef __FUNCT__
1739 #define __FUNCT__ "TSMonitor"
1740 /*
1741      Runs the user provided monitor routines, if they exists.
1742 */
1743 PetscErrorCode TSMonitor(TS ts,PetscInt step,PetscReal ptime,Vec x)
1744 {
1745   PetscErrorCode ierr;
1746   PetscInt       i,n = ts->numbermonitors;
1747 
1748   PetscFunctionBegin;
1749   for (i=0; i<n; i++) {
1750     ierr = (*ts->monitor[i])(ts,step,ptime,x,ts->monitorcontext[i]);CHKERRQ(ierr);
1751   }
1752   PetscFunctionReturn(0);
1753 }
1754 
1755 /* ------------------------------------------------------------------------*/
1756 
1757 #undef __FUNCT__
1758 #define __FUNCT__ "TSMonitorLGCreate"
1759 /*@C
1760    TSMonitorLGCreate - Creates a line graph context for use with
1761    TS to monitor convergence of preconditioned residual norms.
1762 
1763    Collective on TS
1764 
1765    Input Parameters:
1766 +  host - the X display to open, or null for the local machine
1767 .  label - the title to put in the title bar
1768 .  x, y - the screen coordinates of the upper left coordinate of the window
1769 -  m, n - the screen width and height in pixels
1770 
1771    Output Parameter:
1772 .  draw - the drawing context
1773 
1774    Options Database Key:
1775 .  -ts_monitor_draw - automatically sets line graph monitor
1776 
1777    Notes:
1778    Use TSMonitorLGDestroy() to destroy this line graph, not PetscDrawLGDestroy().
1779 
1780    Level: intermediate
1781 
1782 .keywords: TS, monitor, line graph, residual, seealso
1783 
1784 .seealso: TSMonitorLGDestroy(), TSMonitorSet()
1785 
1786 @*/
1787 PetscErrorCode PETSCTS_DLLEXPORT TSMonitorLGCreate(const char host[],const char label[],int x,int y,int m,int n,PetscDrawLG *draw)
1788 {
1789   PetscDraw      win;
1790   PetscErrorCode ierr;
1791 
1792   PetscFunctionBegin;
1793   ierr = PetscDrawCreate(PETSC_COMM_SELF,host,label,x,y,m,n,&win);CHKERRQ(ierr);
1794   ierr = PetscDrawSetType(win,PETSC_DRAW_X);CHKERRQ(ierr);
1795   ierr = PetscDrawLGCreate(win,1,draw);CHKERRQ(ierr);
1796   ierr = PetscDrawLGIndicateDataPoints(*draw);CHKERRQ(ierr);
1797 
1798   ierr = PetscLogObjectParent(*draw,win);CHKERRQ(ierr);
1799   PetscFunctionReturn(0);
1800 }
1801 
1802 #undef __FUNCT__
1803 #define __FUNCT__ "TSMonitorLG"
1804 PetscErrorCode TSMonitorLG(TS ts,PetscInt n,PetscReal ptime,Vec v,void *monctx)
1805 {
1806   PetscDrawLG    lg = (PetscDrawLG) monctx;
1807   PetscReal      x,y = ptime;
1808   PetscErrorCode ierr;
1809 
1810   PetscFunctionBegin;
1811   if (!monctx) {
1812     MPI_Comm    comm;
1813     PetscViewer viewer;
1814 
1815     ierr   = PetscObjectGetComm((PetscObject)ts,&comm);CHKERRQ(ierr);
1816     viewer = PETSC_VIEWER_DRAW_(comm);
1817     ierr   = PetscViewerDrawGetDrawLG(viewer,0,&lg);CHKERRQ(ierr);
1818   }
1819 
1820   if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);}
1821   x = (PetscReal)n;
1822   ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr);
1823   if (n < 20 || (n % 5)) {
1824     ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr);
1825   }
1826   PetscFunctionReturn(0);
1827 }
1828 
1829 #undef __FUNCT__
1830 #define __FUNCT__ "TSMonitorLGDestroy"
1831 /*@C
1832    TSMonitorLGDestroy - Destroys a line graph context that was created
1833    with TSMonitorLGCreate().
1834 
1835    Collective on PetscDrawLG
1836 
1837    Input Parameter:
1838 .  draw - the drawing context
1839 
1840    Level: intermediate
1841 
1842 .keywords: TS, monitor, line graph, destroy
1843 
1844 .seealso: TSMonitorLGCreate(),  TSMonitorSet(), TSMonitorLG();
1845 @*/
1846 PetscErrorCode PETSCTS_DLLEXPORT TSMonitorLGDestroy(PetscDrawLG drawlg)
1847 {
1848   PetscDraw      draw;
1849   PetscErrorCode ierr;
1850 
1851   PetscFunctionBegin;
1852   ierr = PetscDrawLGGetDraw(drawlg,&draw);CHKERRQ(ierr);
1853   ierr = PetscDrawDestroy(draw);CHKERRQ(ierr);
1854   ierr = PetscDrawLGDestroy(drawlg);CHKERRQ(ierr);
1855   PetscFunctionReturn(0);
1856 }
1857 
1858 #undef __FUNCT__
1859 #define __FUNCT__ "TSGetTime"
1860 /*@
1861    TSGetTime - Gets the current time.
1862 
1863    Not Collective
1864 
1865    Input Parameter:
1866 .  ts - the TS context obtained from TSCreate()
1867 
1868    Output Parameter:
1869 .  t  - the current time
1870 
1871    Level: beginner
1872 
1873 .seealso: TSSetInitialTimeStep(), TSGetTimeStep()
1874 
1875 .keywords: TS, get, time
1876 @*/
1877 PetscErrorCode PETSCTS_DLLEXPORT TSGetTime(TS ts,PetscReal* t)
1878 {
1879   PetscFunctionBegin;
1880   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
1881   PetscValidDoublePointer(t,2);
1882   *t = ts->ptime;
1883   PetscFunctionReturn(0);
1884 }
1885 
1886 #undef __FUNCT__
1887 #define __FUNCT__ "TSSetTime"
1888 /*@
1889    TSSetTime - Allows one to reset the time.
1890 
1891    Collective on TS
1892 
1893    Input Parameters:
1894 +  ts - the TS context obtained from TSCreate()
1895 -  time - the time
1896 
1897    Level: intermediate
1898 
1899 .seealso: TSGetTime(), TSSetDuration()
1900 
1901 .keywords: TS, set, time
1902 @*/
1903 PetscErrorCode PETSCTS_DLLEXPORT TSSetTime(TS ts, PetscReal t)
1904 {
1905   PetscFunctionBegin;
1906   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
1907   ts->ptime = t;
1908   PetscFunctionReturn(0);
1909 }
1910 
1911 #undef __FUNCT__
1912 #define __FUNCT__ "TSSetOptionsPrefix"
1913 /*@C
1914    TSSetOptionsPrefix - Sets the prefix used for searching for all
1915    TS options in the database.
1916 
1917    Collective on TS
1918 
1919    Input Parameter:
1920 +  ts     - The TS context
1921 -  prefix - The prefix to prepend to all option names
1922 
1923    Notes:
1924    A hyphen (-) must NOT be given at the beginning of the prefix name.
1925    The first character of all runtime options is AUTOMATICALLY the
1926    hyphen.
1927 
1928    Level: advanced
1929 
1930 .keywords: TS, set, options, prefix, database
1931 
1932 .seealso: TSSetFromOptions()
1933 
1934 @*/
1935 PetscErrorCode PETSCTS_DLLEXPORT TSSetOptionsPrefix(TS ts,const char prefix[])
1936 {
1937   PetscErrorCode ierr;
1938 
1939   PetscFunctionBegin;
1940   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
1941   ierr = PetscObjectSetOptionsPrefix((PetscObject)ts,prefix);CHKERRQ(ierr);
1942   switch(ts->problem_type) {
1943     case TS_NONLINEAR:
1944       if (ts->snes) {
1945         ierr = SNESSetOptionsPrefix(ts->snes,prefix);CHKERRQ(ierr);
1946       }
1947       break;
1948     case TS_LINEAR:
1949       if (ts->ksp) {
1950         ierr = KSPSetOptionsPrefix(ts->ksp,prefix);CHKERRQ(ierr);
1951       }
1952       break;
1953   }
1954   PetscFunctionReturn(0);
1955 }
1956 
1957 
1958 #undef __FUNCT__
1959 #define __FUNCT__ "TSAppendOptionsPrefix"
1960 /*@C
1961    TSAppendOptionsPrefix - Appends to the prefix used for searching for all
1962    TS options in the database.
1963 
1964    Collective on TS
1965 
1966    Input Parameter:
1967 +  ts     - The TS context
1968 -  prefix - The prefix to prepend to all option names
1969 
1970    Notes:
1971    A hyphen (-) must NOT be given at the beginning of the prefix name.
1972    The first character of all runtime options is AUTOMATICALLY the
1973    hyphen.
1974 
1975    Level: advanced
1976 
1977 .keywords: TS, append, options, prefix, database
1978 
1979 .seealso: TSGetOptionsPrefix()
1980 
1981 @*/
1982 PetscErrorCode PETSCTS_DLLEXPORT TSAppendOptionsPrefix(TS ts,const char prefix[])
1983 {
1984   PetscErrorCode ierr;
1985 
1986   PetscFunctionBegin;
1987   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
1988   ierr = PetscObjectAppendOptionsPrefix((PetscObject)ts,prefix);CHKERRQ(ierr);
1989   switch(ts->problem_type) {
1990     case TS_NONLINEAR:
1991       if (ts->snes) {
1992         ierr = SNESAppendOptionsPrefix(ts->snes,prefix);CHKERRQ(ierr);
1993       }
1994       break;
1995     case TS_LINEAR:
1996       if (ts->ksp) {
1997         ierr = KSPAppendOptionsPrefix(ts->ksp,prefix);CHKERRQ(ierr);
1998       }
1999       break;
2000   }
2001   PetscFunctionReturn(0);
2002 }
2003 
2004 #undef __FUNCT__
2005 #define __FUNCT__ "TSGetOptionsPrefix"
2006 /*@C
2007    TSGetOptionsPrefix - Sets the prefix used for searching for all
2008    TS options in the database.
2009 
2010    Not Collective
2011 
2012    Input Parameter:
2013 .  ts - The TS context
2014 
2015    Output Parameter:
2016 .  prefix - A pointer to the prefix string used
2017 
2018    Notes: On the fortran side, the user should pass in a string 'prifix' of
2019    sufficient length to hold the prefix.
2020 
2021    Level: intermediate
2022 
2023 .keywords: TS, get, options, prefix, database
2024 
2025 .seealso: TSAppendOptionsPrefix()
2026 @*/
2027 PetscErrorCode PETSCTS_DLLEXPORT TSGetOptionsPrefix(TS ts,const char *prefix[])
2028 {
2029   PetscErrorCode ierr;
2030 
2031   PetscFunctionBegin;
2032   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
2033   PetscValidPointer(prefix,2);
2034   ierr = PetscObjectGetOptionsPrefix((PetscObject)ts,prefix);CHKERRQ(ierr);
2035   PetscFunctionReturn(0);
2036 }
2037 
2038 #undef __FUNCT__
2039 #define __FUNCT__ "TSGetRHSJacobian"
2040 /*@C
2041    TSGetRHSJacobian - Returns the Jacobian J at the present timestep.
2042 
2043    Not Collective, but parallel objects are returned if TS is parallel
2044 
2045    Input Parameter:
2046 .  ts  - The TS context obtained from TSCreate()
2047 
2048    Output Parameters:
2049 +  J   - The Jacobian J of F, where U_t = F(U,t)
2050 .  M   - The preconditioner matrix, usually the same as J
2051 - ctx - User-defined context for Jacobian evaluation routine
2052 
2053    Notes: You can pass in PETSC_NULL for any return argument you do not need.
2054 
2055    Level: intermediate
2056 
2057 .seealso: TSGetTimeStep(), TSGetMatrices(), TSGetTime(), TSGetTimeStepNumber()
2058 
2059 .keywords: TS, timestep, get, matrix, Jacobian
2060 @*/
2061 PetscErrorCode PETSCTS_DLLEXPORT TSGetRHSJacobian(TS ts,Mat *J,Mat *M,void **ctx)
2062 {
2063   PetscFunctionBegin;
2064   if (J) *J = ts->Arhs;
2065   if (M) *M = ts->B;
2066   if (ctx) *ctx = ts->jacP;
2067   PetscFunctionReturn(0);
2068 }
2069 
2070 #undef __FUNCT__
2071 #define __FUNCT__ "TSGetIJacobian"
2072 /*@C
2073    TSGetIJacobian - Returns the implicit Jacobian at the present timestep.
2074 
2075    Not Collective, but parallel objects are returned if TS is parallel
2076 
2077    Input Parameter:
2078 .  ts  - The TS context obtained from TSCreate()
2079 
2080    Output Parameters:
2081 +  A   - The Jacobian of F(t,U,U_t)
2082 .  B   - The preconditioner matrix, often the same as A
2083 .  f   - The function to compute the matrices
2084 - ctx - User-defined context for Jacobian evaluation routine
2085 
2086    Notes: You can pass in PETSC_NULL for any return argument you do not need.
2087 
2088    Level: advanced
2089 
2090 .seealso: TSGetTimeStep(), TSGetRHSJacobian(), TSGetMatrices(), TSGetTime(), TSGetTimeStepNumber()
2091 
2092 .keywords: TS, timestep, get, matrix, Jacobian
2093 @*/
2094 PetscErrorCode PETSCTS_DLLEXPORT TSGetIJacobian(TS ts,Mat *A,Mat *B,TSIJacobian *f,void **ctx)
2095 {
2096   PetscFunctionBegin;
2097   if (A) *A = ts->A;
2098   if (B) *B = ts->B;
2099   if (f) *f = ts->ops->ijacobian;
2100   if (ctx) *ctx = ts->jacP;
2101   PetscFunctionReturn(0);
2102 }
2103 
2104 #undef __FUNCT__
2105 #define __FUNCT__ "TSMonitorSolution"
2106 /*@C
2107    TSMonitorSolution - Monitors progress of the TS solvers by calling
2108    VecView() for the solution at each timestep
2109 
2110    Collective on TS
2111 
2112    Input Parameters:
2113 +  ts - the TS context
2114 .  step - current time-step
2115 .  ptime - current time
2116 -  dummy - either a viewer or PETSC_NULL
2117 
2118    Level: intermediate
2119 
2120 .keywords: TS,  vector, monitor, view
2121 
2122 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView()
2123 @*/
2124 PetscErrorCode PETSCTS_DLLEXPORT TSMonitorSolution(TS ts,PetscInt step,PetscReal ptime,Vec x,void *dummy)
2125 {
2126   PetscErrorCode ierr;
2127   PetscViewer    viewer = (PetscViewer) dummy;
2128 
2129   PetscFunctionBegin;
2130   if (!dummy) {
2131     viewer = PETSC_VIEWER_DRAW_(((PetscObject)ts)->comm);
2132   }
2133   ierr = VecView(x,viewer);CHKERRQ(ierr);
2134   PetscFunctionReturn(0);
2135 }
2136 
2137 
2138 #undef __FUNCT__
2139 #define __FUNCT__ "TSSetDM"
2140 /*@
2141    TSSetDM - Sets the DM that may be used by some preconditioners
2142 
2143    Collective on TS
2144 
2145    Input Parameters:
2146 +  ts - the preconditioner context
2147 -  dm - the dm
2148 
2149    Level: intermediate
2150 
2151 
2152 .seealso: TSGetDM(), SNESSetDM(), SNESGetDM()
2153 @*/
2154 PetscErrorCode PETSCTS_DLLEXPORT TSSetDM(TS ts,DM dm)
2155 {
2156   PetscErrorCode ierr;
2157 
2158   PetscFunctionBegin;
2159   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
2160   if (ts->dm) {ierr = DMDestroy(ts->dm);CHKERRQ(ierr);}
2161   ts->dm = dm;
2162   ierr = PetscObjectReference((PetscObject)ts->dm);CHKERRQ(ierr);
2163   if (ts->snes) {ierr = SNESSetDM(ts->snes,dm);CHKERRQ(ierr);}
2164   PetscFunctionReturn(0);
2165 }
2166 
2167 #undef __FUNCT__
2168 #define __FUNCT__ "TSGetDM"
2169 /*@
2170    TSGetDM - Gets the DM that may be used by some preconditioners
2171 
2172    Collective on TS
2173 
2174    Input Parameter:
2175 . ts - the preconditioner context
2176 
2177    Output Parameter:
2178 .  dm - the dm
2179 
2180    Level: intermediate
2181 
2182 
2183 .seealso: TSSetDM(), SNESSetDM(), SNESGetDM()
2184 @*/
2185 PetscErrorCode PETSCTS_DLLEXPORT TSGetDM(TS ts,DM *dm)
2186 {
2187   PetscFunctionBegin;
2188   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
2189   *dm = ts->dm;
2190   PetscFunctionReturn(0);
2191 }
2192 
2193 #undef __FUNCT__
2194 #define __FUNCT__ "SNESTSFormFunction"
2195 /*@
2196    SNESTSFormFunction - Function to evaluate nonlinear residual
2197 
2198    Collective on SNES
2199 
2200    Input Parameter:
2201 + snes - nonlinear solver
2202 . X - the current state at which to evaluate the residual
2203 - ctx - user context, must be a TS
2204 
2205    Output Parameter:
2206 . F - the nonlinear residual
2207 
2208    Notes:
2209    This function is not normally called by users and is automatically registered with the SNES used by TS.
2210    It is most frequently passed to MatFDColoringSetFunction().
2211 
2212    Level: advanced
2213 
2214 .seealso: SNESSetFunction(), MatFDColoringSetFunction()
2215 @*/
2216 PetscErrorCode PETSCTS_DLLEXPORT SNESTSFormFunction(SNES snes,Vec X,Vec F,void *ctx)
2217 {
2218   TS ts = (TS)ctx;
2219   PetscErrorCode ierr;
2220 
2221   PetscFunctionBegin;
2222   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2223   PetscValidHeaderSpecific(X,VEC_CLASSID,2);
2224   PetscValidHeaderSpecific(F,VEC_CLASSID,3);
2225   PetscValidHeaderSpecific(ts,TS_CLASSID,4);
2226   ierr = (ts->ops->snesfunction)(snes,X,F,ts);CHKERRQ(ierr);
2227   PetscFunctionReturn(0);
2228 }
2229 
2230 #undef __FUNCT__
2231 #define __FUNCT__ "SNESTSFormJacobian"
2232 /*@
2233    SNESTSFormJacobian - Function to evaluate the Jacobian
2234 
2235    Collective on SNES
2236 
2237    Input Parameter:
2238 + snes - nonlinear solver
2239 . X - the current state at which to evaluate the residual
2240 - ctx - user context, must be a TS
2241 
2242    Output Parameter:
2243 + A - the Jacobian
2244 . B - the preconditioning matrix (may be the same as A)
2245 - flag - indicates any structure change in the matrix
2246 
2247    Notes:
2248    This function is not normally called by users and is automatically registered with the SNES used by TS.
2249 
2250    Level: developer
2251 
2252 .seealso: SNESSetJacobian()
2253 @*/
2254 PetscErrorCode PETSCTS_DLLEXPORT SNESTSFormJacobian(SNES snes,Vec X,Mat *A,Mat *B,MatStructure *flag,void *ctx)
2255 {
2256   TS ts = (TS)ctx;
2257   PetscErrorCode ierr;
2258 
2259   PetscFunctionBegin;
2260   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2261   PetscValidHeaderSpecific(X,VEC_CLASSID,2);
2262   PetscValidPointer(A,3);
2263   PetscValidHeaderSpecific(*A,MAT_CLASSID,3);
2264   PetscValidPointer(B,4);
2265   PetscValidHeaderSpecific(*B,MAT_CLASSID,4);
2266   PetscValidPointer(flag,5);
2267   PetscValidHeaderSpecific(ts,TS_CLASSID,6);
2268   ierr = (ts->ops->snesjacobian)(snes,X,A,B,flag,ts);CHKERRQ(ierr);
2269   PetscFunctionReturn(0);
2270 }
2271