xref: /petsc/src/ts/interface/ts.c (revision 5c6c1daec53e1d9ab0bec9db5309fd8fc7645b8d)
1 
2 #include <petsc-private/tsimpl.h>        /*I "petscts.h"  I*/
3 #include <petscdmshell.h>
4 
5 /* Logging support */
6 PetscClassId  TS_CLASSID, DMTS_CLASSID;
7 PetscLogEvent  TS_Step, TS_PseudoComputeTimeStep, TS_FunctionEval, TS_JacobianEval;
8 
9 const char *const TSExactFinalTimeOptions[] = {"STEPOVER","INTERPOLATE","MATCHSTEP","TSExactFinalTimeOption","TS_EXACTFINALTIME_",0};
10 
11 #undef __FUNCT__
12 #define __FUNCT__ "TSSetTypeFromOptions"
13 /*
14   TSSetTypeFromOptions - Sets the type of ts from user options.
15 
16   Collective on TS
17 
18   Input Parameter:
19 . ts - The ts
20 
21   Level: intermediate
22 
23 .keywords: TS, set, options, database, type
24 .seealso: TSSetFromOptions(), TSSetType()
25 */
26 static PetscErrorCode TSSetTypeFromOptions(TS ts)
27 {
28   PetscBool      opt;
29   const char     *defaultType;
30   char           typeName[256];
31   PetscErrorCode ierr;
32 
33   PetscFunctionBegin;
34   if (((PetscObject)ts)->type_name) {
35     defaultType = ((PetscObject)ts)->type_name;
36   } else {
37     defaultType = TSEULER;
38   }
39 
40   if (!TSRegisterAllCalled) {ierr = TSRegisterAll(PETSC_NULL);CHKERRQ(ierr);}
41   ierr = PetscOptionsList("-ts_type", "TS method"," TSSetType", TSList, defaultType, typeName, 256, &opt);CHKERRQ(ierr);
42   if (opt) {
43     ierr = TSSetType(ts, typeName);CHKERRQ(ierr);
44   } else {
45     ierr = TSSetType(ts, defaultType);CHKERRQ(ierr);
46   }
47   PetscFunctionReturn(0);
48 }
49 
50 #undef __FUNCT__
51 #define __FUNCT__ "TSSetFromOptions"
52 /*@
53    TSSetFromOptions - Sets various TS parameters from user options.
54 
55    Collective on TS
56 
57    Input Parameter:
58 .  ts - the TS context obtained from TSCreate()
59 
60    Options Database Keys:
61 +  -ts_type <type> - TSEULER, TSBEULER, TSSUNDIALS, TSPSEUDO, TSCN, TSRK, TSTHETA, TSGL, TSSSP
62 .  -ts_max_steps maxsteps - maximum number of time-steps to take
63 .  -ts_final_time time - maximum time to compute to
64 .  -ts_dt dt - initial time step
65 .  -ts_monitor - print information at each timestep
66 .  -ts_monitor_lg_timestep - Monitor timestep size graphically
67 .  -ts_monitor_lg_solution - Monitor solution graphically
68 .  -ts_monitor_lg_error - Monitor error graphically
69 .  -ts_monitor_lg_snes_iterations - Monitor number nonlinear iterations for each timestep graphically
70 .  -ts_monitor_lg_ksp_iterations - Monitor number nonlinear iterations for each timestep graphically
71 .  -ts_monitor_sp_eig - Monitor eigenvalues of linearized operator graphically
72 .  -ts_monitor_draw_solution - Monitor solution graphically
73 .  -ts_monitor_draw_solution - Monitor solution graphically
74 .  -ts_monitor_draw_error - Monitor error graphically
75 .  -ts_monitor_draw_solution_binary <filename> - Save each solution to a binary file
76 -  -ts_monitor_draw_solution_vtk <filename.vts> - Save each time step to a binary file, use filename-%%03D.vts
77 
78    Level: beginner
79 
80 .keywords: TS, timestep, set, options, database
81 
82 .seealso: TSGetType()
83 @*/
84 PetscErrorCode  TSSetFromOptions(TS ts)
85 {
86   PetscBool      opt,flg;
87   PetscErrorCode ierr;
88   PetscViewer    monviewer;
89   char           monfilename[PETSC_MAX_PATH_LEN];
90   SNES           snes;
91   TSAdapt        adapt;
92   PetscReal      time_step;
93   TSExactFinalTimeOption      eftopt;
94 
95   PetscFunctionBegin;
96   PetscValidHeaderSpecific(ts, TS_CLASSID,1);
97   ierr = PetscObjectOptionsBegin((PetscObject)ts);CHKERRQ(ierr);
98     /* Handle TS type options */
99     ierr = TSSetTypeFromOptions(ts);CHKERRQ(ierr);
100 
101     /* Handle generic TS options */
102     ierr = PetscOptionsInt("-ts_max_steps","Maximum number of time steps","TSSetDuration",ts->max_steps,&ts->max_steps,PETSC_NULL);CHKERRQ(ierr);
103     ierr = PetscOptionsReal("-ts_final_time","Time to run to","TSSetDuration",ts->max_time,&ts->max_time,PETSC_NULL);CHKERRQ(ierr);
104     ierr = PetscOptionsReal("-ts_init_time","Initial time","TSSetTime",ts->ptime,&ts->ptime,PETSC_NULL);CHKERRQ(ierr);
105     ierr = PetscOptionsReal("-ts_dt","Initial time step","TSSetTimeStep",ts->time_step,&time_step,&flg);CHKERRQ(ierr);
106     if (flg) {
107       ierr = TSSetTimeStep(ts,time_step);CHKERRQ(ierr);
108     }
109     ierr = PetscOptionsEnum("-ts_exact_final_time","Option for handling of final time step","TSSetExactFinalTime",TSExactFinalTimeOptions,(PetscEnum)ts->exact_final_time,(PetscEnum*)&eftopt,&flg);CHKERRQ(ierr);
110     if (flg) {ierr = TSSetExactFinalTime(ts,eftopt);CHKERRQ(ierr);}
111     ierr = PetscOptionsInt("-ts_max_snes_failures","Maximum number of nonlinear solve failures","TSSetMaxSNESFailures",ts->max_snes_failures,&ts->max_snes_failures,PETSC_NULL);CHKERRQ(ierr);
112     ierr = PetscOptionsInt("-ts_max_reject","Maximum number of step rejections before step fails","TSSetMaxStepRejections",ts->max_reject,&ts->max_reject,PETSC_NULL);CHKERRQ(ierr);
113     ierr = PetscOptionsBool("-ts_error_if_step_fails","Error if no step succeeds","TSSetErrorIfStepFails",ts->errorifstepfailed,&ts->errorifstepfailed,PETSC_NULL);CHKERRQ(ierr);
114     ierr = PetscOptionsReal("-ts_rtol","Relative tolerance for local truncation error","TSSetTolerances",ts->rtol,&ts->rtol,PETSC_NULL);CHKERRQ(ierr);
115     ierr = PetscOptionsReal("-ts_atol","Absolute tolerance for local truncation error","TSSetTolerances",ts->atol,&ts->atol,PETSC_NULL);CHKERRQ(ierr);
116 
117     /* Monitor options */
118     ierr = PetscOptionsString("-ts_monitor","Monitor timestep size","TSMonitorDefault","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr);
119     if (flg) {
120       ierr = PetscViewerASCIIOpen(((PetscObject)ts)->comm,monfilename,&monviewer);CHKERRQ(ierr);
121       ierr = TSMonitorSet(ts,TSMonitorDefault,monviewer,(PetscErrorCode (*)(void**))PetscViewerDestroy);CHKERRQ(ierr);
122     }
123     ierr = PetscOptionsString("-ts_monitor_python","Use Python function","TSMonitorSet",0,monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr);
124     if (flg) {ierr = PetscPythonMonitorSet((PetscObject)ts,monfilename);CHKERRQ(ierr);}
125 
126     ierr = PetscOptionsName("-ts_monitor_lg_timestep","Monitor timestep size graphically","TSMonitorLGTimeStep",&opt);CHKERRQ(ierr);
127     if (opt) {
128       TSMonitorLGCtx ctx;
129       PetscInt       howoften = 1;
130 
131       ierr = PetscOptionsInt("-ts_monitor_lg_timestep","Monitor timestep size graphically","TSMonitorLGTimeStep",howoften,&howoften,PETSC_NULL);CHKERRQ(ierr);
132       ierr = TSMonitorLGCtxCreate(((PetscObject)ts)->comm,0,0,PETSC_DECIDE,PETSC_DECIDE,300,300,howoften,&ctx);CHKERRQ(ierr);
133       ierr = TSMonitorSet(ts,TSMonitorLGTimeStep,ctx,(PetscErrorCode (*)(void**))TSMonitorLGCtxDestroy);CHKERRQ(ierr);
134     }
135     ierr = PetscOptionsName("-ts_monitor_lg_solution","Monitor solution graphically","TSMonitorLGSolution",&opt);CHKERRQ(ierr);
136     if (opt) {
137       TSMonitorLGCtx ctx;
138       PetscInt       howoften = 1;
139 
140       ierr = PetscOptionsInt("-ts_monitor_lg_solution","Monitor solution graphically","TSMonitorLGSolution",howoften,&howoften,PETSC_NULL);CHKERRQ(ierr);
141       ierr = TSMonitorLGCtxCreate(PETSC_COMM_SELF,0,0,PETSC_DECIDE,PETSC_DECIDE,600,400,howoften,&ctx);
142       ierr = TSMonitorSet(ts,TSMonitorLGSolution,ctx,(PetscErrorCode (*)(void**))TSMonitorLGCtxDestroy);CHKERRQ(ierr);
143     }
144     ierr = PetscOptionsName("-ts_monitor_lg_error","Monitor error graphically","TSMonitorLGError",&opt);CHKERRQ(ierr);
145     if (opt) {
146       TSMonitorLGCtx ctx;
147       PetscInt       howoften = 1;
148 
149       ierr = PetscOptionsInt("-ts_monitor_lg_error","Monitor error graphically","TSMonitorLGError",howoften,&howoften,PETSC_NULL);CHKERRQ(ierr);
150       ierr = TSMonitorLGCtxCreate(PETSC_COMM_SELF,0,0,PETSC_DECIDE,PETSC_DECIDE,600,400,howoften,&ctx);
151       ierr = TSMonitorSet(ts,TSMonitorLGError,ctx,(PetscErrorCode (*)(void**))TSMonitorLGCtxDestroy);CHKERRQ(ierr);
152     }
153     ierr = PetscOptionsName("-ts_monitor_lg_snes_iterations","Monitor number nonlinear iterations for each timestep graphically","TSMonitorLGSNESIterations",&opt);CHKERRQ(ierr);
154     if (opt) {
155       TSMonitorLGCtx ctx;
156       PetscInt       howoften = 1;
157 
158       ierr = PetscOptionsInt("-ts_monitor_lg_snes_iterations","Monitor number nonlinear iterations for each timestep graphically","TSMonitorLGSNESIterations",howoften,&howoften,PETSC_NULL);CHKERRQ(ierr);
159       ierr = TSMonitorLGCtxCreate(PETSC_COMM_SELF,0,0,PETSC_DECIDE,PETSC_DECIDE,300,300,howoften,&ctx);
160       ierr = TSMonitorSet(ts,TSMonitorLGSNESIterations,ctx,(PetscErrorCode (*)(void**))TSMonitorLGCtxDestroy);CHKERRQ(ierr);
161     }
162     ierr = PetscOptionsName("-ts_monitor_lg_ksp_iterations","Monitor number nonlinear iterations for each timestep graphically","TSMonitorLGKSPIterations",&opt);CHKERRQ(ierr);
163     if (opt) {
164       TSMonitorLGCtx ctx;
165       PetscInt       howoften = 1;
166 
167       ierr = PetscOptionsInt("-ts_monitor_lg_ksp_iterations","Monitor number nonlinear iterations for each timestep graphically","TSMonitorLGKSPIterations",howoften,&howoften,PETSC_NULL);CHKERRQ(ierr);
168       ierr = TSMonitorLGCtxCreate(PETSC_COMM_SELF,0,0,PETSC_DECIDE,PETSC_DECIDE,300,300,howoften,&ctx);
169       ierr = TSMonitorSet(ts,TSMonitorLGKSPIterations,ctx,(PetscErrorCode (*)(void**))TSMonitorLGCtxDestroy);CHKERRQ(ierr);
170     }
171     ierr = PetscOptionsName("-ts_monitor_sp_eig","Monitor eigenvalues of linearized operator graphically","TSMonitorSPEig",&opt);CHKERRQ(ierr);
172     if (opt) {
173       TSMonitorSPEigCtx ctx;
174       PetscInt          howoften = 1;
175 
176       ierr = PetscOptionsInt("-ts_monitor_sp_eig","Monitor eigenvalues of linearized operator graphically","TSMonitorSPEig",howoften,&howoften,PETSC_NULL);CHKERRQ(ierr);
177       ierr = TSMonitorSPEigCtxCreate(PETSC_COMM_SELF,0,0,PETSC_DECIDE,PETSC_DECIDE,600,400,howoften,&ctx);
178       ierr = TSMonitorSet(ts,TSMonitorSPEig,ctx,(PetscErrorCode (*)(void**))TSMonitorSPEigCtxDestroy);CHKERRQ(ierr);
179     }
180     opt  = PETSC_FALSE;
181     ierr = PetscOptionsName("-ts_monitor_draw_solution","Monitor solution graphically","TSMonitorDrawSolution",&opt);CHKERRQ(ierr);
182     if (opt) {
183       TSMonitorDrawCtx ctx;
184       PetscInt         howoften = 1;
185 
186       ierr = PetscOptionsInt("-ts_monitor_draw_solution","Monitor solution graphically","TSMonitorDrawSolution",howoften,&howoften,PETSC_NULL);CHKERRQ(ierr);
187       ierr = TSMonitorDrawCtxCreate(((PetscObject)ts)->comm,0,0,PETSC_DECIDE,PETSC_DECIDE,600,400,howoften,&ctx);
188       ierr = TSMonitorSet(ts,TSMonitorDrawSolution,ctx,(PetscErrorCode (*)(void**))TSMonitorDrawCtxDestroy);CHKERRQ(ierr);
189     }
190     opt  = PETSC_FALSE;
191     ierr = PetscOptionsName("-ts_monitor_draw_error","Monitor error graphically","TSMonitorDrawError",&opt);CHKERRQ(ierr);
192     if (opt) {
193       TSMonitorDrawCtx ctx;
194       PetscInt         howoften = 1;
195 
196       ierr = PetscOptionsInt("-ts_monitor_draw_error","Monitor error graphically","TSMonitorDrawError",howoften,&howoften,PETSC_NULL);CHKERRQ(ierr);
197       ierr = TSMonitorDrawCtxCreate(((PetscObject)ts)->comm,0,0,PETSC_DECIDE,PETSC_DECIDE,600,400,howoften,&ctx);
198       ierr = TSMonitorSet(ts,TSMonitorDrawError,ctx,(PetscErrorCode (*)(void**))TSMonitorDrawCtxDestroy);CHKERRQ(ierr);
199     }
200     opt  = PETSC_FALSE;
201     ierr = PetscOptionsString("-ts_monitor_draw_solution_binary","Save each solution to a binary file","TSMonitorSolutionBinary",0,monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr);
202     if (flg) {
203       PetscViewer ctx;
204       if (monfilename[0]) {
205         ierr = PetscViewerBinaryOpen(((PetscObject)ts)->comm,monfilename,FILE_MODE_WRITE,&ctx);CHKERRQ(ierr);
206       } else {
207         ctx = PETSC_VIEWER_BINARY_(((PetscObject)ts)->comm);
208       }
209       ierr = TSMonitorSet(ts,TSMonitorSolutionBinary,ctx,(PetscErrorCode (*)(void**))PetscViewerDestroy);CHKERRQ(ierr);
210     }
211     opt  = PETSC_FALSE;
212     ierr = PetscOptionsString("-ts_monitor_draw_solution_vtk","Save each time step to a binary file, use filename-%%03D.vts","TSMonitorSolutionVTK",0,monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr);
213     if (flg) {
214       const char *ptr,*ptr2;
215       char *filetemplate;
216       if (!monfilename[0]) SETERRQ(((PetscObject)ts)->comm,PETSC_ERR_USER,"-ts_monitor_draw_solution_vtk requires a file template, e.g. filename-%%03D.vts");
217       /* Do some cursory validation of the input. */
218       ierr = PetscStrstr(monfilename,"%",(char**)&ptr);CHKERRQ(ierr);
219       if (!ptr) SETERRQ(((PetscObject)ts)->comm,PETSC_ERR_USER,"-ts_monitor_draw_solution_vtk requires a file template, e.g. filename-%%03D.vts");
220       for (ptr++ ; ptr && *ptr; ptr++) {
221         ierr = PetscStrchr("DdiouxX",*ptr,(char**)&ptr2);CHKERRQ(ierr);
222         if (!ptr2 && (*ptr < '0' || '9' < *ptr)) SETERRQ(((PetscObject)ts)->comm,PETSC_ERR_USER,"Invalid file template argument to -ts_monitor_draw_solution_vtk, should look like filename-%%03D.vts");
223         if (ptr2) break;
224       }
225       ierr = PetscStrallocpy(monfilename,&filetemplate);CHKERRQ(ierr);
226       ierr = TSMonitorSet(ts,TSMonitorSolutionVTK,filetemplate,(PetscErrorCode (*)(void**))TSMonitorSolutionVTKDestroy);CHKERRQ(ierr);
227     }
228 
229     ierr = TSGetTSAdapt(ts,&adapt);CHKERRQ(ierr);
230     ierr = TSAdaptSetFromOptions(adapt);CHKERRQ(ierr);
231 
232     ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr);
233     if (ts->problem_type == TS_LINEAR) {ierr = SNESSetType(snes,SNESKSPONLY);CHKERRQ(ierr);}
234 
235     /* Handle specific TS options */
236     if (ts->ops->setfromoptions) {
237       ierr = (*ts->ops->setfromoptions)(ts);CHKERRQ(ierr);
238     }
239 
240     /* process any options handlers added with PetscObjectAddOptionsHandler() */
241     ierr = PetscObjectProcessOptionsHandlers((PetscObject)ts);CHKERRQ(ierr);
242   ierr = PetscOptionsEnd();CHKERRQ(ierr);
243   PetscFunctionReturn(0);
244 }
245 
246 #undef __FUNCT__
247 #undef __FUNCT__
248 #define __FUNCT__ "TSComputeRHSJacobian"
249 /*@
250    TSComputeRHSJacobian - Computes the Jacobian matrix that has been
251       set with TSSetRHSJacobian().
252 
253    Collective on TS and Vec
254 
255    Input Parameters:
256 +  ts - the TS context
257 .  t - current timestep
258 -  U - input vector
259 
260    Output Parameters:
261 +  A - Jacobian matrix
262 .  B - optional preconditioning matrix
263 -  flag - flag indicating matrix structure
264 
265    Notes:
266    Most users should not need to explicitly call this routine, as it
267    is used internally within the nonlinear solvers.
268 
269    See KSPSetOperators() for important information about setting the
270    flag parameter.
271 
272    Level: developer
273 
274 .keywords: SNES, compute, Jacobian, matrix
275 
276 .seealso:  TSSetRHSJacobian(), KSPSetOperators()
277 @*/
278 PetscErrorCode  TSComputeRHSJacobian(TS ts,PetscReal t,Vec U,Mat *A,Mat *B,MatStructure *flg)
279 {
280   PetscErrorCode ierr;
281   PetscInt       Ustate;
282   DM             dm;
283   DMTS           tsdm;
284   TSRHSJacobian  rhsjacobianfunc;
285   void           *ctx;
286   TSIJacobian    ijacobianfunc;
287 
288   PetscFunctionBegin;
289   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
290   PetscValidHeaderSpecific(U,VEC_CLASSID,3);
291   PetscCheckSameComm(ts,1,U,3);
292   ierr = TSGetDM(ts,&dm);CHKERRQ(ierr);
293   ierr = DMGetDMTS(dm,&tsdm);CHKERRQ(ierr);
294   ierr = DMTSGetRHSJacobian(dm,&rhsjacobianfunc,&ctx);CHKERRQ(ierr);
295   ierr = DMTSGetIJacobian(dm,&ijacobianfunc,PETSC_NULL);CHKERRQ(ierr);
296   ierr = PetscObjectStateQuery((PetscObject)U,&Ustate);CHKERRQ(ierr);
297   if (ts->rhsjacobian.time == t && (ts->problem_type == TS_LINEAR || (ts->rhsjacobian.X == U && ts->rhsjacobian.Xstate == Ustate))) {
298     *flg = ts->rhsjacobian.mstructure;
299     PetscFunctionReturn(0);
300   }
301 
302   if (!rhsjacobianfunc && !ijacobianfunc) SETERRQ(((PetscObject)ts)->comm,PETSC_ERR_USER,"Must call TSSetRHSJacobian() and / or TSSetIJacobian()");
303 
304   if (rhsjacobianfunc) {
305     ierr = PetscLogEventBegin(TS_JacobianEval,ts,U,*A,*B);CHKERRQ(ierr);
306     *flg = DIFFERENT_NONZERO_PATTERN;
307     PetscStackPush("TS user Jacobian function");
308     ierr = (*rhsjacobianfunc)(ts,t,U,A,B,flg,ctx);CHKERRQ(ierr);
309     PetscStackPop;
310     ierr = PetscLogEventEnd(TS_JacobianEval,ts,U,*A,*B);CHKERRQ(ierr);
311     /* make sure user returned a correct Jacobian and preconditioner */
312     PetscValidHeaderSpecific(*A,MAT_CLASSID,4);
313     PetscValidHeaderSpecific(*B,MAT_CLASSID,5);
314   } else {
315     ierr = MatZeroEntries(*A);CHKERRQ(ierr);
316     if (*A != *B) {ierr = MatZeroEntries(*B);CHKERRQ(ierr);}
317     *flg = SAME_NONZERO_PATTERN;
318   }
319   ts->rhsjacobian.time = t;
320   ts->rhsjacobian.X = U;
321   ierr = PetscObjectStateQuery((PetscObject)U,&ts->rhsjacobian.Xstate);CHKERRQ(ierr);
322   ts->rhsjacobian.mstructure = *flg;
323   PetscFunctionReturn(0);
324 }
325 
326 #undef __FUNCT__
327 #define __FUNCT__ "TSComputeRHSFunction"
328 /*@
329    TSComputeRHSFunction - Evaluates the right-hand-side function.
330 
331    Collective on TS and Vec
332 
333    Input Parameters:
334 +  ts - the TS context
335 .  t - current time
336 -  U - state vector
337 
338    Output Parameter:
339 .  y - right hand side
340 
341    Note:
342    Most users should not need to explicitly call this routine, as it
343    is used internally within the nonlinear solvers.
344 
345    Level: developer
346 
347 .keywords: TS, compute
348 
349 .seealso: TSSetRHSFunction(), TSComputeIFunction()
350 @*/
351 PetscErrorCode TSComputeRHSFunction(TS ts,PetscReal t,Vec U,Vec y)
352 {
353   PetscErrorCode ierr;
354   TSRHSFunction  rhsfunction;
355   TSIFunction    ifunction;
356   void           *ctx;
357   DM             dm;
358 
359   PetscFunctionBegin;
360   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
361   PetscValidHeaderSpecific(U,VEC_CLASSID,3);
362   PetscValidHeaderSpecific(y,VEC_CLASSID,4);
363   ierr = TSGetDM(ts,&dm);CHKERRQ(ierr);
364   ierr = DMTSGetRHSFunction(dm,&rhsfunction,&ctx);CHKERRQ(ierr);
365   ierr = DMTSGetIFunction(dm,&ifunction,PETSC_NULL);CHKERRQ(ierr);
366 
367   if (!rhsfunction && !ifunction) SETERRQ(((PetscObject)ts)->comm,PETSC_ERR_USER,"Must call TSSetRHSFunction() and / or TSSetIFunction()");
368 
369   ierr = PetscLogEventBegin(TS_FunctionEval,ts,U,y,0);CHKERRQ(ierr);
370   if (rhsfunction) {
371     PetscStackPush("TS user right-hand-side function");
372     ierr = (*rhsfunction)(ts,t,U,y,ctx);CHKERRQ(ierr);
373     PetscStackPop;
374   } else {
375     ierr = VecZeroEntries(y);CHKERRQ(ierr);
376   }
377 
378   ierr = PetscLogEventEnd(TS_FunctionEval,ts,U,y,0);CHKERRQ(ierr);
379   PetscFunctionReturn(0);
380 }
381 
382 #undef __FUNCT__
383 #define __FUNCT__ "TSComputeSolutionFunction"
384 /*@
385    TSComputeSolutionFunction - Evaluates the solution function.
386 
387    Collective on TS and Vec
388 
389    Input Parameters:
390 +  ts - the TS context
391 -  t - current time
392 
393    Output Parameter:
394 .  U - the solution
395 
396    Note:
397    Most users should not need to explicitly call this routine, as it
398    is used internally within the nonlinear solvers.
399 
400    Level: developer
401 
402 .keywords: TS, compute
403 
404 .seealso: TSSetSolutionFunction(), TSSetRHSFunction(), TSComputeIFunction()
405 @*/
406 PetscErrorCode TSComputeSolutionFunction(TS ts,PetscReal t,Vec U)
407 {
408   PetscErrorCode     ierr;
409   TSSolutionFunction solutionfunction;
410   void               *ctx;
411   DM                 dm;
412 
413   PetscFunctionBegin;
414   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
415   PetscValidHeaderSpecific(U,VEC_CLASSID,3);
416   ierr = TSGetDM(ts,&dm);CHKERRQ(ierr);
417   ierr = DMTSGetSolutionFunction(dm,&solutionfunction,&ctx);CHKERRQ(ierr);
418 
419   if (solutionfunction) {
420     PetscStackPush("TS user right-hand-side function");
421     ierr = (*solutionfunction)(ts,t,U,ctx);CHKERRQ(ierr);
422     PetscStackPop;
423   }
424   PetscFunctionReturn(0);
425 }
426 
427 #undef __FUNCT__
428 #define __FUNCT__ "TSGetRHSVec_Private"
429 static PetscErrorCode TSGetRHSVec_Private(TS ts,Vec *Frhs)
430 {
431   Vec            F;
432   PetscErrorCode ierr;
433 
434   PetscFunctionBegin;
435   *Frhs = PETSC_NULL;
436   ierr = TSGetIFunction(ts,&F,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);
437   if (!ts->Frhs) {
438     ierr = VecDuplicate(F,&ts->Frhs);CHKERRQ(ierr);
439   }
440   *Frhs = ts->Frhs;
441   PetscFunctionReturn(0);
442 }
443 
444 #undef __FUNCT__
445 #define __FUNCT__ "TSGetRHSMats_Private"
446 static PetscErrorCode TSGetRHSMats_Private(TS ts,Mat *Arhs,Mat *Brhs)
447 {
448   Mat            A,B;
449   PetscErrorCode ierr;
450 
451   PetscFunctionBegin;
452   ierr = TSGetIJacobian(ts,&A,&B,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);
453   if (Arhs) {
454     if (!ts->Arhs) {
455       ierr = MatDuplicate(A,MAT_DO_NOT_COPY_VALUES,&ts->Arhs);CHKERRQ(ierr);
456     }
457     *Arhs = ts->Arhs;
458   }
459   if (Brhs) {
460     if (!ts->Brhs) {
461       ierr = MatDuplicate(B,MAT_DO_NOT_COPY_VALUES,&ts->Brhs);CHKERRQ(ierr);
462     }
463     *Brhs = ts->Brhs;
464   }
465   PetscFunctionReturn(0);
466 }
467 
468 #undef __FUNCT__
469 #define __FUNCT__ "TSComputeIFunction"
470 /*@
471    TSComputeIFunction - Evaluates the DAE residual written in implicit form F(t,U,Udot)=0
472 
473    Collective on TS and Vec
474 
475    Input Parameters:
476 +  ts - the TS context
477 .  t - current time
478 .  U - state vector
479 .  Udot - time derivative of state vector
480 -  imex - flag indicates if the method is IMEX so that the RHSFunction should be kept separate
481 
482    Output Parameter:
483 .  Y - right hand side
484 
485    Note:
486    Most users should not need to explicitly call this routine, as it
487    is used internally within the nonlinear solvers.
488 
489    If the user did did not write their equations in implicit form, this
490    function recasts them in implicit form.
491 
492    Level: developer
493 
494 .keywords: TS, compute
495 
496 .seealso: TSSetIFunction(), TSComputeRHSFunction()
497 @*/
498 PetscErrorCode TSComputeIFunction(TS ts,PetscReal t,Vec U,Vec Udot,Vec Y,PetscBool imex)
499 {
500   PetscErrorCode ierr;
501   TSIFunction    ifunction;
502   TSRHSFunction  rhsfunction;
503   void           *ctx;
504   DM             dm;
505 
506   PetscFunctionBegin;
507   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
508   PetscValidHeaderSpecific(U,VEC_CLASSID,3);
509   PetscValidHeaderSpecific(Udot,VEC_CLASSID,4);
510   PetscValidHeaderSpecific(Y,VEC_CLASSID,5);
511 
512   ierr = TSGetDM(ts,&dm);CHKERRQ(ierr);
513   ierr = DMTSGetIFunction(dm,&ifunction,&ctx);CHKERRQ(ierr);
514   ierr = DMTSGetRHSFunction(dm,&rhsfunction,PETSC_NULL);CHKERRQ(ierr);
515 
516   if (!rhsfunction && !ifunction) SETERRQ(((PetscObject)ts)->comm,PETSC_ERR_USER,"Must call TSSetRHSFunction() and / or TSSetIFunction()");
517 
518   ierr = PetscLogEventBegin(TS_FunctionEval,ts,U,Udot,Y);CHKERRQ(ierr);
519   if (ifunction) {
520     PetscStackPush("TS user implicit function");
521     ierr = (*ifunction)(ts,t,U,Udot,Y,ctx);CHKERRQ(ierr);
522     PetscStackPop;
523   }
524   if (imex) {
525     if (!ifunction) {
526       ierr = VecCopy(Udot,Y);CHKERRQ(ierr);
527     }
528   } else if (rhsfunction) {
529     if (ifunction) {
530       Vec Frhs;
531       ierr = TSGetRHSVec_Private(ts,&Frhs);CHKERRQ(ierr);
532       ierr = TSComputeRHSFunction(ts,t,U,Frhs);CHKERRQ(ierr);
533       ierr = VecAXPY(Y,-1,Frhs);CHKERRQ(ierr);
534     } else {
535       ierr = TSComputeRHSFunction(ts,t,U,Y);CHKERRQ(ierr);
536       ierr = VecAYPX(Y,-1,Udot);CHKERRQ(ierr);
537     }
538   }
539   ierr = PetscLogEventEnd(TS_FunctionEval,ts,U,Udot,Y);CHKERRQ(ierr);
540   PetscFunctionReturn(0);
541 }
542 
543 #undef __FUNCT__
544 #define __FUNCT__ "TSComputeIJacobian"
545 /*@
546    TSComputeIJacobian - Evaluates the Jacobian of the DAE
547 
548    Collective on TS and Vec
549 
550    Input
551       Input Parameters:
552 +  ts - the TS context
553 .  t - current timestep
554 .  U - state vector
555 .  Udot - time derivative of state vector
556 .  shift - shift to apply, see note below
557 -  imex - flag indicates if the method is IMEX so that the RHSJacobian should be kept separate
558 
559    Output Parameters:
560 +  A - Jacobian matrix
561 .  B - optional preconditioning matrix
562 -  flag - flag indicating matrix structure
563 
564    Notes:
565    If F(t,U,Udot)=0 is the DAE, the required Jacobian is
566 
567    dF/dU + shift*dF/dUdot
568 
569    Most users should not need to explicitly call this routine, as it
570    is used internally within the nonlinear solvers.
571 
572    Level: developer
573 
574 .keywords: TS, compute, Jacobian, matrix
575 
576 .seealso:  TSSetIJacobian()
577 @*/
578 PetscErrorCode TSComputeIJacobian(TS ts,PetscReal t,Vec U,Vec Udot,PetscReal shift,Mat *A,Mat *B,MatStructure *flg,PetscBool imex)
579 {
580   PetscInt       Ustate, Udotstate;
581   PetscErrorCode ierr;
582   TSIJacobian    ijacobian;
583   TSRHSJacobian  rhsjacobian;
584   DM             dm;
585   void           *ctx;
586 
587   PetscFunctionBegin;
588 
589   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
590   PetscValidHeaderSpecific(U,VEC_CLASSID,3);
591   PetscValidHeaderSpecific(Udot,VEC_CLASSID,4);
592   PetscValidPointer(A,6);
593   PetscValidHeaderSpecific(*A,MAT_CLASSID,6);
594   PetscValidPointer(B,7);
595   PetscValidHeaderSpecific(*B,MAT_CLASSID,7);
596   PetscValidPointer(flg,8);
597 
598   ierr = TSGetDM(ts,&dm);CHKERRQ(ierr);
599   ierr = DMTSGetIJacobian(dm,&ijacobian,&ctx);CHKERRQ(ierr);
600   ierr = DMTSGetRHSJacobian(dm,&rhsjacobian,PETSC_NULL);CHKERRQ(ierr);
601 
602   ierr = PetscObjectStateQuery((PetscObject)U,&Ustate);CHKERRQ(ierr);
603   ierr = PetscObjectStateQuery((PetscObject)Udot,&Udotstate);CHKERRQ(ierr);
604   if (ts->ijacobian.time == t && (ts->problem_type == TS_LINEAR || (ts->ijacobian.X == U && ts->ijacobian.Xstate == Ustate && ts->ijacobian.Xdot == Udot && ts->ijacobian.Xdotstate == Udotstate && ts->ijacobian.imex == imex))) {
605     *flg = ts->ijacobian.mstructure;
606     ierr = MatScale(*A, shift / ts->ijacobian.shift);CHKERRQ(ierr);
607     PetscFunctionReturn(0);
608   }
609 
610   if (!rhsjacobian && !ijacobian) SETERRQ(((PetscObject)ts)->comm,PETSC_ERR_USER,"Must call TSSetRHSJacobian() and / or TSSetIJacobian()");
611 
612   *flg = SAME_NONZERO_PATTERN;  /* In case we're solving a linear problem in which case it wouldn't get initialized below. */
613   ierr = PetscLogEventBegin(TS_JacobianEval,ts,U,*A,*B);CHKERRQ(ierr);
614   if (ijacobian) {
615     *flg = DIFFERENT_NONZERO_PATTERN;
616     PetscStackPush("TS user implicit Jacobian");
617     ierr = (*ijacobian)(ts,t,U,Udot,shift,A,B,flg,ctx);CHKERRQ(ierr);
618     PetscStackPop;
619     /* make sure user returned a correct Jacobian and preconditioner */
620     PetscValidHeaderSpecific(*A,MAT_CLASSID,4);
621     PetscValidHeaderSpecific(*B,MAT_CLASSID,5);
622   }
623   if (imex) {
624     if (!ijacobian) {  /* system was written as Udot = G(t,U) */
625       ierr = MatZeroEntries(*A);CHKERRQ(ierr);
626       ierr = MatShift(*A,shift);CHKERRQ(ierr);
627       if (*A != *B) {
628         ierr = MatZeroEntries(*B);CHKERRQ(ierr);
629         ierr = MatShift(*B,shift);CHKERRQ(ierr);
630       }
631       *flg = SAME_PRECONDITIONER;
632     }
633   } else {
634     if (!ijacobian) {
635       ierr = TSComputeRHSJacobian(ts,t,U,A,B,flg);CHKERRQ(ierr);
636       ierr = MatScale(*A,-1);CHKERRQ(ierr);
637       ierr = MatShift(*A,shift);CHKERRQ(ierr);
638       if (*A != *B) {
639         ierr = MatScale(*B,-1);CHKERRQ(ierr);
640         ierr = MatShift(*B,shift);CHKERRQ(ierr);
641       }
642     } else if (rhsjacobian) {
643       Mat Arhs,Brhs;
644       MatStructure axpy,flg2 = DIFFERENT_NONZERO_PATTERN;
645       ierr = TSGetRHSMats_Private(ts,&Arhs,&Brhs);CHKERRQ(ierr);
646       ierr = TSComputeRHSJacobian(ts,t,U,&Arhs,&Brhs,&flg2);CHKERRQ(ierr);
647       axpy = (*flg == flg2) ? SAME_NONZERO_PATTERN : DIFFERENT_NONZERO_PATTERN;
648       ierr = MatAXPY(*A,-1,Arhs,axpy);CHKERRQ(ierr);
649       if (*A != *B) {
650         ierr = MatAXPY(*B,-1,Brhs,axpy);CHKERRQ(ierr);
651       }
652       *flg = PetscMin(*flg,flg2);
653     }
654   }
655 
656   ts->ijacobian.time = t;
657   ts->ijacobian.X = U;
658   ts->ijacobian.Xdot = Udot;
659   ierr = PetscObjectStateQuery((PetscObject)U,&ts->ijacobian.Xstate);CHKERRQ(ierr);
660   ierr = PetscObjectStateQuery((PetscObject)Udot,&ts->ijacobian.Xdotstate);CHKERRQ(ierr);
661   ts->ijacobian.shift = shift;
662   ts->ijacobian.imex = imex;
663   ts->ijacobian.mstructure = *flg;
664   ierr = PetscLogEventEnd(TS_JacobianEval,ts,U,*A,*B);CHKERRQ(ierr);
665   PetscFunctionReturn(0);
666 }
667 
668 #undef __FUNCT__
669 #define __FUNCT__ "TSSetRHSFunction"
670 /*@C
671     TSSetRHSFunction - Sets the routine for evaluating the function,
672     where U_t = G(t,u).
673 
674     Logically Collective on TS
675 
676     Input Parameters:
677 +   ts - the TS context obtained from TSCreate()
678 .   r - vector to put the computed right hand side (or PETSC_NULL to have it created)
679 .   f - routine for evaluating the right-hand-side function
680 -   ctx - [optional] user-defined context for private data for the
681           function evaluation routine (may be PETSC_NULL)
682 
683     Calling sequence of func:
684 $     func (TS ts,PetscReal t,Vec u,Vec F,void *ctx);
685 
686 +   t - current timestep
687 .   u - input vector
688 .   F - function vector
689 -   ctx - [optional] user-defined function context
690 
691     Level: beginner
692 
693 .keywords: TS, timestep, set, right-hand-side, function
694 
695 .seealso: TSSetRHSJacobian(), TSSetIJacobian()
696 @*/
697 PetscErrorCode  TSSetRHSFunction(TS ts,Vec r,PetscErrorCode (*f)(TS,PetscReal,Vec,Vec,void*),void *ctx)
698 {
699   PetscErrorCode ierr;
700   SNES           snes;
701   Vec            ralloc = PETSC_NULL;
702   DM             dm;
703 
704   PetscFunctionBegin;
705   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
706   if (r) PetscValidHeaderSpecific(r,VEC_CLASSID,2);
707 
708   ierr = TSGetDM(ts,&dm);CHKERRQ(ierr);
709   ierr = DMTSSetRHSFunction(dm,f,ctx);CHKERRQ(ierr);
710   ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr);
711   if (!r && !ts->dm && ts->vec_sol) {
712     ierr = VecDuplicate(ts->vec_sol,&ralloc);CHKERRQ(ierr);
713     r = ralloc;
714   }
715   ierr = SNESSetFunction(snes,r,SNESTSFormFunction,ts);CHKERRQ(ierr);
716   ierr = VecDestroy(&ralloc);CHKERRQ(ierr);
717   PetscFunctionReturn(0);
718 }
719 
720 #undef __FUNCT__
721 #define __FUNCT__ "TSSetSolutionFunction"
722 /*@C
723     TSSetSolutionFunction - Provide a function that computes the solution of the ODE or DAE
724 
725     Logically Collective on TS
726 
727     Input Parameters:
728 +   ts - the TS context obtained from TSCreate()
729 .   f - routine for evaluating the solution
730 -   ctx - [optional] user-defined context for private data for the
731           function evaluation routine (may be PETSC_NULL)
732 
733     Calling sequence of func:
734 $     func (TS ts,PetscReal t,Vec u,void *ctx);
735 
736 +   t - current timestep
737 .   u - output vector
738 -   ctx - [optional] user-defined function context
739 
740     Notes:
741     This routine is used for testing accuracy of time integration schemes when you already know the solution.
742     If analytic solutions are not known for your system, consider using the Method of Manufactured Solutions to
743     create closed-form solutions with non-physical forcing terms.
744 
745     For low-dimensional problems solved in serial, such as small discrete systems, TSMonitorLGError() can be used to monitor the error history.
746 
747     Level: beginner
748 
749 .keywords: TS, timestep, set, right-hand-side, function
750 
751 .seealso: TSSetRHSJacobian(), TSSetIJacobian(), TSComputeSolutionFunction()
752 @*/
753 PetscErrorCode  TSSetSolutionFunction(TS ts,PetscErrorCode (*f)(TS,PetscReal,Vec,void*),void *ctx)
754 {
755   PetscErrorCode ierr;
756   DM             dm;
757 
758   PetscFunctionBegin;
759   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
760   ierr = TSGetDM(ts,&dm);CHKERRQ(ierr);
761   ierr = DMTSSetSolutionFunction(dm,f,ctx);CHKERRQ(ierr);
762   PetscFunctionReturn(0);
763 }
764 
765 #undef __FUNCT__
766 #define __FUNCT__ "TSSetRHSJacobian"
767 /*@C
768    TSSetRHSJacobian - Sets the function to compute the Jacobian of F,
769    where U_t = G(U,t), as well as the location to store the matrix.
770 
771    Logically Collective on TS
772 
773    Input Parameters:
774 +  ts  - the TS context obtained from TSCreate()
775 .  A   - Jacobian matrix
776 .  B   - preconditioner matrix (usually same as A)
777 .  f   - the Jacobian evaluation routine
778 -  ctx - [optional] user-defined context for private data for the
779          Jacobian evaluation routine (may be PETSC_NULL)
780 
781    Calling sequence of func:
782 $     func (TS ts,PetscReal t,Vec u,Mat *A,Mat *B,MatStructure *flag,void *ctx);
783 
784 +  t - current timestep
785 .  u - input vector
786 .  A - matrix A, where U_t = A(t)u
787 .  B - preconditioner matrix, usually the same as A
788 .  flag - flag indicating information about the preconditioner matrix
789           structure (same as flag in KSPSetOperators())
790 -  ctx - [optional] user-defined context for matrix evaluation routine
791 
792    Notes:
793    See KSPSetOperators() for important information about setting the flag
794    output parameter in the routine func().  Be sure to read this information!
795 
796    The routine func() takes Mat * as the matrix arguments rather than Mat.
797    This allows the matrix evaluation routine to replace A and/or B with a
798    completely new matrix structure (not just different matrix elements)
799    when appropriate, for instance, if the nonzero structure is changing
800    throughout the global iterations.
801 
802    Level: beginner
803 
804 .keywords: TS, timestep, set, right-hand-side, Jacobian
805 
806 .seealso: SNESDefaultComputeJacobianColor(), TSSetRHSFunction()
807 
808 @*/
809 PetscErrorCode  TSSetRHSJacobian(TS ts,Mat A,Mat B,TSRHSJacobian f,void *ctx)
810 {
811   PetscErrorCode ierr;
812   SNES           snes;
813   DM             dm;
814   TSIJacobian    ijacobian;
815 
816   PetscFunctionBegin;
817   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
818   if (A) PetscValidHeaderSpecific(A,MAT_CLASSID,2);
819   if (B) PetscValidHeaderSpecific(B,MAT_CLASSID,3);
820   if (A) PetscCheckSameComm(ts,1,A,2);
821   if (B) PetscCheckSameComm(ts,1,B,3);
822 
823   ierr = TSGetDM(ts,&dm);CHKERRQ(ierr);
824   ierr = DMTSSetRHSJacobian(dm,f,ctx);CHKERRQ(ierr);
825   ierr = DMTSGetIJacobian(dm,&ijacobian,PETSC_NULL);CHKERRQ(ierr);
826 
827   ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr);
828   if (!ijacobian) {
829     ierr = SNESSetJacobian(snes,A,B,SNESTSFormJacobian,ts);CHKERRQ(ierr);
830   }
831   if (A) {
832     ierr = PetscObjectReference((PetscObject)A);CHKERRQ(ierr);
833     ierr = MatDestroy(&ts->Arhs);CHKERRQ(ierr);
834     ts->Arhs = A;
835   }
836   if (B) {
837     ierr = PetscObjectReference((PetscObject)B);CHKERRQ(ierr);
838     ierr = MatDestroy(&ts->Brhs);CHKERRQ(ierr);
839     ts->Brhs = B;
840   }
841   PetscFunctionReturn(0);
842 }
843 
844 
845 #undef __FUNCT__
846 #define __FUNCT__ "TSSetIFunction"
847 /*@C
848    TSSetIFunction - Set the function to compute F(t,U,U_t) where F() = 0 is the DAE to be solved.
849 
850    Logically Collective on TS
851 
852    Input Parameters:
853 +  ts  - the TS context obtained from TSCreate()
854 .  r   - vector to hold the residual (or PETSC_NULL to have it created internally)
855 .  f   - the function evaluation routine
856 -  ctx - user-defined context for private data for the function evaluation routine (may be PETSC_NULL)
857 
858    Calling sequence of f:
859 $  f(TS ts,PetscReal t,Vec u,Vec u_t,Vec F,ctx);
860 
861 +  t   - time at step/stage being solved
862 .  u   - state vector
863 .  u_t - time derivative of state vector
864 .  F   - function vector
865 -  ctx - [optional] user-defined context for matrix evaluation routine
866 
867    Important:
868    The user MUST call either this routine, TSSetRHSFunction().  This routine must be used when not solving an ODE, for example a DAE.
869 
870    Level: beginner
871 
872 .keywords: TS, timestep, set, DAE, Jacobian
873 
874 .seealso: TSSetRHSJacobian(), TSSetRHSFunction(), TSSetIJacobian()
875 @*/
876 PetscErrorCode  TSSetIFunction(TS ts,Vec res,TSIFunction f,void *ctx)
877 {
878   PetscErrorCode ierr;
879   SNES           snes;
880   Vec            resalloc = PETSC_NULL;
881   DM             dm;
882 
883   PetscFunctionBegin;
884   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
885   if (res) PetscValidHeaderSpecific(res,VEC_CLASSID,2);
886 
887   ierr = TSGetDM(ts,&dm);CHKERRQ(ierr);
888   ierr = DMTSSetIFunction(dm,f,ctx);CHKERRQ(ierr);
889 
890   ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr);
891   if (!res && !ts->dm && ts->vec_sol) {
892     ierr = VecDuplicate(ts->vec_sol,&resalloc);CHKERRQ(ierr);
893     res = resalloc;
894   }
895   ierr = SNESSetFunction(snes,res,SNESTSFormFunction,ts);CHKERRQ(ierr);
896   ierr = VecDestroy(&resalloc);CHKERRQ(ierr);
897 
898   PetscFunctionReturn(0);
899 }
900 
901 #undef __FUNCT__
902 #define __FUNCT__ "TSGetIFunction"
903 /*@C
904    TSGetIFunction - Returns the vector where the implicit residual is stored and the function/contex to compute it.
905 
906    Not Collective
907 
908    Input Parameter:
909 .  ts - the TS context
910 
911    Output Parameter:
912 +  r - vector to hold residual (or PETSC_NULL)
913 .  func - the function to compute residual (or PETSC_NULL)
914 -  ctx - the function context (or PETSC_NULL)
915 
916    Level: advanced
917 
918 .keywords: TS, nonlinear, get, function
919 
920 .seealso: TSSetIFunction(), SNESGetFunction()
921 @*/
922 PetscErrorCode TSGetIFunction(TS ts,Vec *r,TSIFunction *func,void **ctx)
923 {
924   PetscErrorCode ierr;
925   SNES           snes;
926   DM             dm;
927 
928   PetscFunctionBegin;
929   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
930   ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr);
931   ierr = SNESGetFunction(snes,r,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);
932   ierr = TSGetDM(ts,&dm);CHKERRQ(ierr);
933   ierr = DMTSGetIFunction(dm,func,ctx);CHKERRQ(ierr);
934   PetscFunctionReturn(0);
935 }
936 
937 #undef __FUNCT__
938 #define __FUNCT__ "TSGetRHSFunction"
939 /*@C
940    TSGetRHSFunction - Returns the vector where the right hand side is stored and the function/context to compute it.
941 
942    Not Collective
943 
944    Input Parameter:
945 .  ts - the TS context
946 
947    Output Parameter:
948 +  r - vector to hold computed right hand side (or PETSC_NULL)
949 .  func - the function to compute right hand side (or PETSC_NULL)
950 -  ctx - the function context (or PETSC_NULL)
951 
952    Level: advanced
953 
954 .keywords: TS, nonlinear, get, function
955 
956 .seealso: TSSetRhsfunction(), SNESGetFunction()
957 @*/
958 PetscErrorCode TSGetRHSFunction(TS ts,Vec *r,TSRHSFunction *func,void **ctx)
959 {
960   PetscErrorCode ierr;
961   SNES           snes;
962   DM             dm;
963 
964   PetscFunctionBegin;
965   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
966   ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr);
967   ierr = SNESGetFunction(snes,r,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);
968   ierr = TSGetDM(ts,&dm);CHKERRQ(ierr);
969   ierr = DMTSGetRHSFunction(dm,func,ctx);CHKERRQ(ierr);
970   PetscFunctionReturn(0);
971 }
972 
973 #undef __FUNCT__
974 #define __FUNCT__ "TSSetIJacobian"
975 /*@C
976    TSSetIJacobian - Set the function to compute the matrix dF/dU + a*dF/dU_t where F(t,U,U_t) is the function
977         you provided with TSSetIFunction().
978 
979    Logically Collective on TS
980 
981    Input Parameters:
982 +  ts  - the TS context obtained from TSCreate()
983 .  A   - Jacobian matrix
984 .  B   - preconditioning matrix for A (may be same as A)
985 .  f   - the Jacobian evaluation routine
986 -  ctx - user-defined context for private data for the Jacobian evaluation routine (may be PETSC_NULL)
987 
988    Calling sequence of f:
989 $  f(TS ts,PetscReal t,Vec U,Vec U_t,PetscReal a,Mat *A,Mat *B,MatStructure *flag,void *ctx);
990 
991 +  t    - time at step/stage being solved
992 .  U    - state vector
993 .  U_t  - time derivative of state vector
994 .  a    - shift
995 .  A    - Jacobian of F(t,U,W+a*U), equivalent to dF/dU + a*dF/dU_t
996 .  B    - preconditioning matrix for A, may be same as A
997 .  flag - flag indicating information about the preconditioner matrix
998           structure (same as flag in KSPSetOperators())
999 -  ctx  - [optional] user-defined context for matrix evaluation routine
1000 
1001    Notes:
1002    The matrices A and B are exactly the matrices that are used by SNES for the nonlinear solve.
1003 
1004    The matrix dF/dU + a*dF/dU_t you provide turns out to be
1005    the Jacobian of F(t,U,W+a*U) where F(t,U,U_t) = 0 is the DAE to be solved.
1006    The time integrator internally approximates U_t by W+a*U where the positive "shift"
1007    a and vector W depend on the integration method, step size, and past states. For example with
1008    the backward Euler method a = 1/dt and W = -a*U(previous timestep) so
1009    W + a*U = a*(U - U(previous timestep)) = (U - U(previous timestep))/dt
1010 
1011    Level: beginner
1012 
1013 .keywords: TS, timestep, DAE, Jacobian
1014 
1015 .seealso: TSSetIFunction(), TSSetRHSJacobian(), SNESDefaultComputeJacobianColor(), SNESDefaultComputeJacobian()
1016 
1017 @*/
1018 PetscErrorCode  TSSetIJacobian(TS ts,Mat A,Mat B,TSIJacobian f,void *ctx)
1019 {
1020   PetscErrorCode ierr;
1021   SNES           snes;
1022   DM             dm;
1023 
1024   PetscFunctionBegin;
1025   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
1026   if (A) PetscValidHeaderSpecific(A,MAT_CLASSID,2);
1027   if (B) PetscValidHeaderSpecific(B,MAT_CLASSID,3);
1028   if (A) PetscCheckSameComm(ts,1,A,2);
1029   if (B) PetscCheckSameComm(ts,1,B,3);
1030 
1031   ierr = TSGetDM(ts,&dm);CHKERRQ(ierr);
1032   ierr = DMTSSetIJacobian(dm,f,ctx);CHKERRQ(ierr);
1033 
1034   ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr);
1035   ierr = SNESSetJacobian(snes,A,B,SNESTSFormJacobian,ts);CHKERRQ(ierr);
1036   PetscFunctionReturn(0);
1037 }
1038 
1039 #undef __FUNCT__
1040 #define __FUNCT__ "TSLoad"
1041 /*@C
1042   TSLoad - Loads a KSP that has been stored in binary  with KSPView().
1043 
1044   Collective on PetscViewer
1045 
1046   Input Parameters:
1047 + newdm - the newly loaded TS, this needs to have been created with TSCreate() or
1048            some related function before a call to TSLoad().
1049 - viewer - binary file viewer, obtained from PetscViewerBinaryOpen()
1050 
1051    Level: intermediate
1052 
1053   Notes:
1054    The type is determined by the data in the file, any type set into the TS before this call is ignored.
1055 
1056   Notes for advanced users:
1057   Most users should not need to know the details of the binary storage
1058   format, since TSLoad() and TSView() completely hide these details.
1059   But for anyone who's interested, the standard binary matrix storage
1060   format is
1061 .vb
1062      has not yet been determined
1063 .ve
1064 
1065 .seealso: PetscViewerBinaryOpen(), TSView(), MatLoad(), VecLoad()
1066 @*/
1067 PetscErrorCode  TSLoad(TS ts, PetscViewer viewer)
1068 {
1069   PetscErrorCode ierr;
1070   PetscBool      isbinary;
1071   PetscInt       classid;
1072   char           type[256];
1073   DMTS           sdm;
1074   DM             dm;
1075 
1076   PetscFunctionBegin;
1077   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
1078   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2);
1079   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr);
1080   if (!isbinary) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Invalid viewer; open viewer with PetscViewerBinaryOpen()");
1081 
1082   ierr = PetscViewerBinaryRead(viewer,&classid,1,PETSC_INT);CHKERRQ(ierr);
1083   if (classid != TS_FILE_CLASSID) SETERRQ(((PetscObject)ts)->comm,PETSC_ERR_ARG_WRONG,"Not TS next in file");
1084   ierr = PetscViewerBinaryRead(viewer,type,256,PETSC_CHAR);CHKERRQ(ierr);
1085   ierr = TSSetType(ts, type);CHKERRQ(ierr);
1086   if (ts->ops->load) {
1087     ierr = (*ts->ops->load)(ts,viewer);CHKERRQ(ierr);
1088   }
1089   ierr = DMCreate(((PetscObject)ts)->comm,&dm);CHKERRQ(ierr);
1090   ierr = DMLoad(dm,viewer);CHKERRQ(ierr);
1091   ierr = TSSetDM(ts,dm);CHKERRQ(ierr);
1092   ierr = DMCreateGlobalVector(ts->dm,&ts->vec_sol);CHKERRQ(ierr);
1093   ierr = VecLoad(ts->vec_sol,viewer);CHKERRQ(ierr);
1094   ierr = DMGetDMTS(ts->dm,&sdm);CHKERRQ(ierr);
1095   ierr = DMTSLoad(sdm,viewer);CHKERRQ(ierr);
1096   PetscFunctionReturn(0);
1097 }
1098 
1099 #undef __FUNCT__
1100 #define __FUNCT__ "TSView"
1101 /*@C
1102     TSView - Prints the TS data structure.
1103 
1104     Collective on TS
1105 
1106     Input Parameters:
1107 +   ts - the TS context obtained from TSCreate()
1108 -   viewer - visualization context
1109 
1110     Options Database Key:
1111 .   -ts_view - calls TSView() at end of TSStep()
1112 
1113     Notes:
1114     The available visualization contexts include
1115 +     PETSC_VIEWER_STDOUT_SELF - standard output (default)
1116 -     PETSC_VIEWER_STDOUT_WORLD - synchronized standard
1117          output where only the first processor opens
1118          the file.  All other processors send their
1119          data to the first processor to print.
1120 
1121     The user can open an alternative visualization context with
1122     PetscViewerASCIIOpen() - output to a specified file.
1123 
1124     Level: beginner
1125 
1126 .keywords: TS, timestep, view
1127 
1128 .seealso: PetscViewerASCIIOpen()
1129 @*/
1130 PetscErrorCode  TSView(TS ts,PetscViewer viewer)
1131 {
1132   PetscErrorCode ierr;
1133   TSType         type;
1134   PetscBool      iascii,isstring,isundials,isbinary,isdraw;
1135   DMTS           sdm;
1136 
1137   PetscFunctionBegin;
1138   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
1139   if (!viewer) {
1140     ierr = PetscViewerASCIIGetStdout(((PetscObject)ts)->comm,&viewer);CHKERRQ(ierr);
1141   }
1142   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2);
1143   PetscCheckSameComm(ts,1,viewer,2);
1144 
1145   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
1146   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERSTRING,&isstring);CHKERRQ(ierr);
1147   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr);
1148   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);CHKERRQ(ierr);
1149   if (iascii) {
1150     ierr = PetscObjectPrintClassNamePrefixType((PetscObject)ts,viewer,"TS Object");CHKERRQ(ierr);
1151     ierr = PetscViewerASCIIPrintf(viewer,"  maximum steps=%D\n",ts->max_steps);CHKERRQ(ierr);
1152     ierr = PetscViewerASCIIPrintf(viewer,"  maximum time=%G\n",ts->max_time);CHKERRQ(ierr);
1153     if (ts->problem_type == TS_NONLINEAR) {
1154       ierr = PetscViewerASCIIPrintf(viewer,"  total number of nonlinear solver iterations=%D\n",ts->snes_its);CHKERRQ(ierr);
1155       ierr = PetscViewerASCIIPrintf(viewer,"  total number of nonlinear solve failures=%D\n",ts->num_snes_failures);CHKERRQ(ierr);
1156     }
1157     ierr = PetscViewerASCIIPrintf(viewer,"  total number of linear solver iterations=%D\n",ts->ksp_its);CHKERRQ(ierr);
1158     ierr = PetscViewerASCIIPrintf(viewer,"  total number of rejected steps=%D\n",ts->reject);CHKERRQ(ierr);
1159     ierr = DMGetDMTS(ts->dm,&sdm);CHKERRQ(ierr);
1160     ierr = DMTSView(sdm,viewer);CHKERRQ(ierr);
1161     if (ts->ops->view) {
1162       ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
1163       ierr = (*ts->ops->view)(ts,viewer);CHKERRQ(ierr);
1164       ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
1165     }
1166   } else if (isstring) {
1167     ierr = TSGetType(ts,&type);CHKERRQ(ierr);
1168     ierr = PetscViewerStringSPrintf(viewer," %-7.7s",type);CHKERRQ(ierr);
1169   } else if (isbinary) {
1170     PetscInt         classid = TS_FILE_CLASSID;
1171     MPI_Comm         comm;
1172     PetscMPIInt      rank;
1173     char             type[256];
1174 
1175     ierr = PetscObjectGetComm((PetscObject)ts,&comm);CHKERRQ(ierr);
1176     ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr);
1177     if (!rank) {
1178       ierr = PetscViewerBinaryWrite(viewer,&classid,1,PETSC_INT,PETSC_FALSE);CHKERRQ(ierr);
1179       ierr = PetscStrncpy(type,((PetscObject)ts)->type_name,256);CHKERRQ(ierr);
1180       ierr = PetscViewerBinaryWrite(viewer,type,256,PETSC_CHAR,PETSC_FALSE);CHKERRQ(ierr);
1181     }
1182     if (ts->ops->view) {
1183       ierr = (*ts->ops->view)(ts,viewer);CHKERRQ(ierr);
1184     }
1185     ierr = DMView(ts->dm,viewer);CHKERRQ(ierr);
1186     ierr = VecView(ts->vec_sol,viewer);CHKERRQ(ierr);
1187     ierr = DMGetDMTS(ts->dm,&sdm);CHKERRQ(ierr);
1188     ierr = DMTSView(sdm,viewer);CHKERRQ(ierr);
1189   } else if (isdraw) {
1190     PetscDraw draw;
1191     char      str[36];
1192     PetscReal x,y,bottom,h;
1193 
1194     ierr = PetscViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr);
1195     ierr = PetscDrawGetCurrentPoint(draw,&x,&y);CHKERRQ(ierr);
1196     ierr = PetscStrcpy(str,"TS: ");CHKERRQ(ierr);
1197     ierr = PetscStrcat(str,((PetscObject)ts)->type_name);CHKERRQ(ierr);
1198     ierr = PetscDrawBoxedString(draw,x,y,PETSC_DRAW_BLACK,PETSC_DRAW_BLACK,str,PETSC_NULL,&h);CHKERRQ(ierr);
1199     bottom = y - h;
1200     ierr = PetscDrawPushCurrentPoint(draw,x,bottom);CHKERRQ(ierr);
1201     if (ts->ops->view) {
1202       ierr = (*ts->ops->view)(ts,viewer);CHKERRQ(ierr);
1203     }
1204     ierr = PetscDrawPopCurrentPoint(draw);CHKERRQ(ierr);
1205   }
1206   ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
1207   ierr = PetscObjectTypeCompare((PetscObject)ts,TSSUNDIALS,&isundials);CHKERRQ(ierr);
1208   ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
1209   PetscFunctionReturn(0);
1210 }
1211 
1212 
1213 #undef __FUNCT__
1214 #define __FUNCT__ "TSSetApplicationContext"
1215 /*@
1216    TSSetApplicationContext - Sets an optional user-defined context for
1217    the timesteppers.
1218 
1219    Logically Collective on TS
1220 
1221    Input Parameters:
1222 +  ts - the TS context obtained from TSCreate()
1223 -  usrP - optional user context
1224 
1225    Level: intermediate
1226 
1227 .keywords: TS, timestep, set, application, context
1228 
1229 .seealso: TSGetApplicationContext()
1230 @*/
1231 PetscErrorCode  TSSetApplicationContext(TS ts,void *usrP)
1232 {
1233   PetscFunctionBegin;
1234   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
1235   ts->user = usrP;
1236   PetscFunctionReturn(0);
1237 }
1238 
1239 #undef __FUNCT__
1240 #define __FUNCT__ "TSGetApplicationContext"
1241 /*@
1242     TSGetApplicationContext - Gets the user-defined context for the
1243     timestepper.
1244 
1245     Not Collective
1246 
1247     Input Parameter:
1248 .   ts - the TS context obtained from TSCreate()
1249 
1250     Output Parameter:
1251 .   usrP - user context
1252 
1253     Level: intermediate
1254 
1255 .keywords: TS, timestep, get, application, context
1256 
1257 .seealso: TSSetApplicationContext()
1258 @*/
1259 PetscErrorCode  TSGetApplicationContext(TS ts,void *usrP)
1260 {
1261   PetscFunctionBegin;
1262   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
1263   *(void**)usrP = ts->user;
1264   PetscFunctionReturn(0);
1265 }
1266 
1267 #undef __FUNCT__
1268 #define __FUNCT__ "TSGetTimeStepNumber"
1269 /*@
1270    TSGetTimeStepNumber - Gets the number of time steps completed.
1271 
1272    Not Collective
1273 
1274    Input Parameter:
1275 .  ts - the TS context obtained from TSCreate()
1276 
1277    Output Parameter:
1278 .  iter - number of steps completed so far
1279 
1280    Level: intermediate
1281 
1282 .keywords: TS, timestep, get, iteration, number
1283 .seealso: TSGetTime(), TSGetTimeStep(), TSSetPreStep(), TSSetPreStage(), TSSetPostStep()
1284 @*/
1285 PetscErrorCode  TSGetTimeStepNumber(TS ts,PetscInt* iter)
1286 {
1287   PetscFunctionBegin;
1288   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
1289   PetscValidIntPointer(iter,2);
1290   *iter = ts->steps;
1291   PetscFunctionReturn(0);
1292 }
1293 
1294 #undef __FUNCT__
1295 #define __FUNCT__ "TSSetInitialTimeStep"
1296 /*@
1297    TSSetInitialTimeStep - Sets the initial timestep to be used,
1298    as well as the initial time.
1299 
1300    Logically Collective on TS
1301 
1302    Input Parameters:
1303 +  ts - the TS context obtained from TSCreate()
1304 .  initial_time - the initial time
1305 -  time_step - the size of the timestep
1306 
1307    Level: intermediate
1308 
1309 .seealso: TSSetTimeStep(), TSGetTimeStep()
1310 
1311 .keywords: TS, set, initial, timestep
1312 @*/
1313 PetscErrorCode  TSSetInitialTimeStep(TS ts,PetscReal initial_time,PetscReal time_step)
1314 {
1315   PetscErrorCode ierr;
1316 
1317   PetscFunctionBegin;
1318   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
1319   ierr = TSSetTimeStep(ts,time_step);CHKERRQ(ierr);
1320   ierr = TSSetTime(ts,initial_time);CHKERRQ(ierr);
1321   PetscFunctionReturn(0);
1322 }
1323 
1324 #undef __FUNCT__
1325 #define __FUNCT__ "TSSetTimeStep"
1326 /*@
1327    TSSetTimeStep - Allows one to reset the timestep at any time,
1328    useful for simple pseudo-timestepping codes.
1329 
1330    Logically Collective on TS
1331 
1332    Input Parameters:
1333 +  ts - the TS context obtained from TSCreate()
1334 -  time_step - the size of the timestep
1335 
1336    Level: intermediate
1337 
1338 .seealso: TSSetInitialTimeStep(), TSGetTimeStep()
1339 
1340 .keywords: TS, set, timestep
1341 @*/
1342 PetscErrorCode  TSSetTimeStep(TS ts,PetscReal time_step)
1343 {
1344   PetscFunctionBegin;
1345   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
1346   PetscValidLogicalCollectiveReal(ts,time_step,2);
1347   ts->time_step = time_step;
1348   ts->time_step_orig = time_step;
1349   PetscFunctionReturn(0);
1350 }
1351 
1352 #undef __FUNCT__
1353 #define __FUNCT__ "TSSetExactFinalTime"
1354 /*@
1355    TSSetExactFinalTime - Determines whether to adapt the final time step to
1356      match the exact final time, interpolate solution to the exact final time,
1357      or just return at the final time TS computed.
1358 
1359   Logically Collective on TS
1360 
1361    Input Parameter:
1362 +   ts - the time-step context
1363 -   eftopt - exact final time option
1364 
1365    Level: beginner
1366 
1367 .seealso: TSExactFinalTime
1368 @*/
1369 PetscErrorCode  TSSetExactFinalTime(TS ts,TSExactFinalTimeOption eftopt)
1370 {
1371   PetscFunctionBegin;
1372   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
1373   PetscValidLogicalCollectiveEnum(ts,eftopt,2);
1374   ts->exact_final_time = eftopt;
1375   PetscFunctionReturn(0);
1376 }
1377 
1378 #undef __FUNCT__
1379 #define __FUNCT__ "TSGetTimeStep"
1380 /*@
1381    TSGetTimeStep - Gets the current timestep size.
1382 
1383    Not Collective
1384 
1385    Input Parameter:
1386 .  ts - the TS context obtained from TSCreate()
1387 
1388    Output Parameter:
1389 .  dt - the current timestep size
1390 
1391    Level: intermediate
1392 
1393 .seealso: TSSetInitialTimeStep(), TSGetTimeStep()
1394 
1395 .keywords: TS, get, timestep
1396 @*/
1397 PetscErrorCode  TSGetTimeStep(TS ts,PetscReal* dt)
1398 {
1399   PetscFunctionBegin;
1400   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
1401   PetscValidRealPointer(dt,2);
1402   *dt = ts->time_step;
1403   PetscFunctionReturn(0);
1404 }
1405 
1406 #undef __FUNCT__
1407 #define __FUNCT__ "TSGetSolution"
1408 /*@
1409    TSGetSolution - Returns the solution at the present timestep. It
1410    is valid to call this routine inside the function that you are evaluating
1411    in order to move to the new timestep. This vector not changed until
1412    the solution at the next timestep has been calculated.
1413 
1414    Not Collective, but Vec returned is parallel if TS is parallel
1415 
1416    Input Parameter:
1417 .  ts - the TS context obtained from TSCreate()
1418 
1419    Output Parameter:
1420 .  v - the vector containing the solution
1421 
1422    Level: intermediate
1423 
1424 .seealso: TSGetTimeStep()
1425 
1426 .keywords: TS, timestep, get, solution
1427 @*/
1428 PetscErrorCode  TSGetSolution(TS ts,Vec *v)
1429 {
1430   PetscFunctionBegin;
1431   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
1432   PetscValidPointer(v,2);
1433   *v = ts->vec_sol;
1434   PetscFunctionReturn(0);
1435 }
1436 
1437 /* ----- Routines to initialize and destroy a timestepper ---- */
1438 #undef __FUNCT__
1439 #define __FUNCT__ "TSSetProblemType"
1440 /*@
1441   TSSetProblemType - Sets the type of problem to be solved.
1442 
1443   Not collective
1444 
1445   Input Parameters:
1446 + ts   - The TS
1447 - type - One of TS_LINEAR, TS_NONLINEAR where these types refer to problems of the forms
1448 .vb
1449          U_t - A U = 0      (linear)
1450          U_t - A(t) U = 0   (linear)
1451          F(t,U,U_t) = 0     (nonlinear)
1452 .ve
1453 
1454    Level: beginner
1455 
1456 .keywords: TS, problem type
1457 .seealso: TSSetUp(), TSProblemType, TS
1458 @*/
1459 PetscErrorCode  TSSetProblemType(TS ts, TSProblemType type)
1460 {
1461   PetscErrorCode ierr;
1462 
1463   PetscFunctionBegin;
1464   PetscValidHeaderSpecific(ts, TS_CLASSID,1);
1465   ts->problem_type = type;
1466   if (type == TS_LINEAR) {
1467     SNES snes;
1468     ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr);
1469     ierr = SNESSetType(snes,SNESKSPONLY);CHKERRQ(ierr);
1470   }
1471   PetscFunctionReturn(0);
1472 }
1473 
1474 #undef __FUNCT__
1475 #define __FUNCT__ "TSGetProblemType"
1476 /*@C
1477   TSGetProblemType - Gets the type of problem to be solved.
1478 
1479   Not collective
1480 
1481   Input Parameter:
1482 . ts   - The TS
1483 
1484   Output Parameter:
1485 . type - One of TS_LINEAR, TS_NONLINEAR where these types refer to problems of the forms
1486 .vb
1487          M U_t = A U
1488          M(t) U_t = A(t) U
1489          F(t,U,U_t)
1490 .ve
1491 
1492    Level: beginner
1493 
1494 .keywords: TS, problem type
1495 .seealso: TSSetUp(), TSProblemType, TS
1496 @*/
1497 PetscErrorCode  TSGetProblemType(TS ts, TSProblemType *type)
1498 {
1499   PetscFunctionBegin;
1500   PetscValidHeaderSpecific(ts, TS_CLASSID,1);
1501   PetscValidIntPointer(type,2);
1502   *type = ts->problem_type;
1503   PetscFunctionReturn(0);
1504 }
1505 
1506 #undef __FUNCT__
1507 #define __FUNCT__ "TSSetUp"
1508 /*@
1509    TSSetUp - Sets up the internal data structures for the later use
1510    of a timestepper.
1511 
1512    Collective on TS
1513 
1514    Input Parameter:
1515 .  ts - the TS context obtained from TSCreate()
1516 
1517    Notes:
1518    For basic use of the TS solvers the user need not explicitly call
1519    TSSetUp(), since these actions will automatically occur during
1520    the call to TSStep().  However, if one wishes to control this
1521    phase separately, TSSetUp() should be called after TSCreate()
1522    and optional routines of the form TSSetXXX(), but before TSStep().
1523 
1524    Level: advanced
1525 
1526 .keywords: TS, timestep, setup
1527 
1528 .seealso: TSCreate(), TSStep(), TSDestroy()
1529 @*/
1530 PetscErrorCode  TSSetUp(TS ts)
1531 {
1532   PetscErrorCode ierr;
1533   DM             dm;
1534   PetscErrorCode (*func)(SNES,Vec,Vec,void*);
1535   PetscErrorCode (*jac)(SNES,Vec,Mat*,Mat*,MatStructure*,void*);
1536   TSIJacobian    ijac;
1537   TSRHSJacobian  rhsjac;
1538 
1539   PetscFunctionBegin;
1540   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
1541   if (ts->setupcalled) PetscFunctionReturn(0);
1542 
1543   if (!((PetscObject)ts)->type_name) {
1544     ierr = TSSetType(ts,TSEULER);CHKERRQ(ierr);
1545   }
1546 
1547   if (!ts->vec_sol) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Must call TSSetSolution() first");
1548 
1549   ierr = TSGetTSAdapt(ts,&ts->adapt);CHKERRQ(ierr);
1550 
1551   if (ts->ops->setup) {
1552     ierr = (*ts->ops->setup)(ts);CHKERRQ(ierr);
1553   }
1554 
1555   /* in the case where we've set a DMTSFunction or what have you, we need the default SNESFunction
1556    to be set right but can't do it elsewhere due to the overreliance on ctx=ts.
1557    */
1558   ierr = TSGetDM(ts,&dm);CHKERRQ(ierr);
1559   ierr = DMSNESGetFunction(dm,&func,PETSC_NULL);CHKERRQ(ierr);
1560   if (!func) {
1561     ierr =DMSNESSetFunction(dm,SNESTSFormFunction,ts);CHKERRQ(ierr);
1562   }
1563   /* if the SNES doesn't have a jacobian set and the TS has an ijacobian or rhsjacobian set, set the SNES to use it.
1564      Otherwise, the SNES will use coloring internally to form the Jacobian.
1565    */
1566   ierr = DMSNESGetJacobian(dm,&jac,PETSC_NULL);CHKERRQ(ierr);
1567   ierr = DMTSGetIJacobian(dm,&ijac,PETSC_NULL);CHKERRQ(ierr);
1568   ierr = DMTSGetRHSJacobian(dm,&rhsjac,PETSC_NULL);CHKERRQ(ierr);
1569   if (!jac && (ijac || rhsjac)) {
1570     ierr = DMSNESSetJacobian(dm,SNESTSFormJacobian,ts);CHKERRQ(ierr);
1571   }
1572   ts->setupcalled = PETSC_TRUE;
1573   PetscFunctionReturn(0);
1574 }
1575 
1576 #undef __FUNCT__
1577 #define __FUNCT__ "TSReset"
1578 /*@
1579    TSReset - Resets a TS context and removes any allocated Vecs and Mats.
1580 
1581    Collective on TS
1582 
1583    Input Parameter:
1584 .  ts - the TS context obtained from TSCreate()
1585 
1586    Level: beginner
1587 
1588 .keywords: TS, timestep, reset
1589 
1590 .seealso: TSCreate(), TSSetup(), TSDestroy()
1591 @*/
1592 PetscErrorCode  TSReset(TS ts)
1593 {
1594   PetscErrorCode ierr;
1595 
1596   PetscFunctionBegin;
1597   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
1598   if (ts->ops->reset) {
1599     ierr = (*ts->ops->reset)(ts);CHKERRQ(ierr);
1600   }
1601   if (ts->snes) {ierr = SNESReset(ts->snes);CHKERRQ(ierr);}
1602   ierr = MatDestroy(&ts->Arhs);CHKERRQ(ierr);
1603   ierr = MatDestroy(&ts->Brhs);CHKERRQ(ierr);
1604   ierr = VecDestroy(&ts->Frhs);CHKERRQ(ierr);
1605   ierr = VecDestroy(&ts->vec_sol);CHKERRQ(ierr);
1606   ierr = VecDestroy(&ts->vatol);CHKERRQ(ierr);
1607   ierr = VecDestroy(&ts->vrtol);CHKERRQ(ierr);
1608   ierr = VecDestroyVecs(ts->nwork,&ts->work);CHKERRQ(ierr);
1609   ts->setupcalled = PETSC_FALSE;
1610   PetscFunctionReturn(0);
1611 }
1612 
1613 #undef __FUNCT__
1614 #define __FUNCT__ "TSDestroy"
1615 /*@
1616    TSDestroy - Destroys the timestepper context that was created
1617    with TSCreate().
1618 
1619    Collective on TS
1620 
1621    Input Parameter:
1622 .  ts - the TS context obtained from TSCreate()
1623 
1624    Level: beginner
1625 
1626 .keywords: TS, timestepper, destroy
1627 
1628 .seealso: TSCreate(), TSSetUp(), TSSolve()
1629 @*/
1630 PetscErrorCode  TSDestroy(TS *ts)
1631 {
1632   PetscErrorCode ierr;
1633 
1634   PetscFunctionBegin;
1635   if (!*ts) PetscFunctionReturn(0);
1636   PetscValidHeaderSpecific((*ts),TS_CLASSID,1);
1637   if (--((PetscObject)(*ts))->refct > 0) {*ts = 0; PetscFunctionReturn(0);}
1638 
1639   ierr = TSReset((*ts));CHKERRQ(ierr);
1640 
1641   /* if memory was published with AMS then destroy it */
1642   ierr = PetscObjectDepublish((*ts));CHKERRQ(ierr);
1643   if ((*ts)->ops->destroy) {ierr = (*(*ts)->ops->destroy)((*ts));CHKERRQ(ierr);}
1644 
1645   ierr = TSAdaptDestroy(&(*ts)->adapt);CHKERRQ(ierr);
1646   ierr = SNESDestroy(&(*ts)->snes);CHKERRQ(ierr);
1647   ierr = DMDestroy(&(*ts)->dm);CHKERRQ(ierr);
1648   ierr = TSMonitorCancel((*ts));CHKERRQ(ierr);
1649 
1650   ierr = PetscHeaderDestroy(ts);CHKERRQ(ierr);
1651   PetscFunctionReturn(0);
1652 }
1653 
1654 #undef __FUNCT__
1655 #define __FUNCT__ "TSGetSNES"
1656 /*@
1657    TSGetSNES - Returns the SNES (nonlinear solver) associated with
1658    a TS (timestepper) context. Valid only for nonlinear problems.
1659 
1660    Not Collective, but SNES is parallel if TS is parallel
1661 
1662    Input Parameter:
1663 .  ts - the TS context obtained from TSCreate()
1664 
1665    Output Parameter:
1666 .  snes - the nonlinear solver context
1667 
1668    Notes:
1669    The user can then directly manipulate the SNES context to set various
1670    options, etc.  Likewise, the user can then extract and manipulate the
1671    KSP, KSP, and PC contexts as well.
1672 
1673    TSGetSNES() does not work for integrators that do not use SNES; in
1674    this case TSGetSNES() returns PETSC_NULL in snes.
1675 
1676    Level: beginner
1677 
1678 .keywords: timestep, get, SNES
1679 @*/
1680 PetscErrorCode  TSGetSNES(TS ts,SNES *snes)
1681 {
1682   PetscErrorCode ierr;
1683 
1684   PetscFunctionBegin;
1685   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
1686   PetscValidPointer(snes,2);
1687   if (!ts->snes) {
1688     ierr = SNESCreate(((PetscObject)ts)->comm,&ts->snes);CHKERRQ(ierr);
1689     ierr = SNESSetFunction(ts->snes,PETSC_NULL,SNESTSFormFunction,ts);CHKERRQ(ierr);
1690     ierr = PetscLogObjectParent(ts,ts->snes);CHKERRQ(ierr);
1691     ierr = PetscObjectIncrementTabLevel((PetscObject)ts->snes,(PetscObject)ts,1);CHKERRQ(ierr);
1692     if (ts->dm) {ierr = SNESSetDM(ts->snes,ts->dm);CHKERRQ(ierr);}
1693     if (ts->problem_type == TS_LINEAR) {
1694       ierr = SNESSetType(ts->snes,SNESKSPONLY);CHKERRQ(ierr);
1695     }
1696   }
1697   *snes = ts->snes;
1698   PetscFunctionReturn(0);
1699 }
1700 
1701 #undef __FUNCT__
1702 #define __FUNCT__ "TSGetKSP"
1703 /*@
1704    TSGetKSP - Returns the KSP (linear solver) associated with
1705    a TS (timestepper) context.
1706 
1707    Not Collective, but KSP is parallel if TS is parallel
1708 
1709    Input Parameter:
1710 .  ts - the TS context obtained from TSCreate()
1711 
1712    Output Parameter:
1713 .  ksp - the nonlinear solver context
1714 
1715    Notes:
1716    The user can then directly manipulate the KSP context to set various
1717    options, etc.  Likewise, the user can then extract and manipulate the
1718    KSP and PC contexts as well.
1719 
1720    TSGetKSP() does not work for integrators that do not use KSP;
1721    in this case TSGetKSP() returns PETSC_NULL in ksp.
1722 
1723    Level: beginner
1724 
1725 .keywords: timestep, get, KSP
1726 @*/
1727 PetscErrorCode  TSGetKSP(TS ts,KSP *ksp)
1728 {
1729   PetscErrorCode ierr;
1730   SNES           snes;
1731 
1732   PetscFunctionBegin;
1733   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
1734   PetscValidPointer(ksp,2);
1735   if (!((PetscObject)ts)->type_name) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"KSP is not created yet. Call TSSetType() first");
1736   if (ts->problem_type != TS_LINEAR) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Linear only; use TSGetSNES()");
1737   ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr);
1738   ierr = SNESGetKSP(snes,ksp);CHKERRQ(ierr);
1739   PetscFunctionReturn(0);
1740 }
1741 
1742 /* ----------- Routines to set solver parameters ---------- */
1743 
1744 #undef __FUNCT__
1745 #define __FUNCT__ "TSGetDuration"
1746 /*@
1747    TSGetDuration - Gets the maximum number of timesteps to use and
1748    maximum time for iteration.
1749 
1750    Not Collective
1751 
1752    Input Parameters:
1753 +  ts       - the TS context obtained from TSCreate()
1754 .  maxsteps - maximum number of iterations to use, or PETSC_NULL
1755 -  maxtime  - final time to iterate to, or PETSC_NULL
1756 
1757    Level: intermediate
1758 
1759 .keywords: TS, timestep, get, maximum, iterations, time
1760 @*/
1761 PetscErrorCode  TSGetDuration(TS ts, PetscInt *maxsteps, PetscReal *maxtime)
1762 {
1763   PetscFunctionBegin;
1764   PetscValidHeaderSpecific(ts, TS_CLASSID,1);
1765   if (maxsteps) {
1766     PetscValidIntPointer(maxsteps,2);
1767     *maxsteps = ts->max_steps;
1768   }
1769   if (maxtime) {
1770     PetscValidScalarPointer(maxtime,3);
1771     *maxtime  = ts->max_time;
1772   }
1773   PetscFunctionReturn(0);
1774 }
1775 
1776 #undef __FUNCT__
1777 #define __FUNCT__ "TSSetDuration"
1778 /*@
1779    TSSetDuration - Sets the maximum number of timesteps to use and
1780    maximum time for iteration.
1781 
1782    Logically Collective on TS
1783 
1784    Input Parameters:
1785 +  ts - the TS context obtained from TSCreate()
1786 .  maxsteps - maximum number of iterations to use
1787 -  maxtime - final time to iterate to
1788 
1789    Options Database Keys:
1790 .  -ts_max_steps <maxsteps> - Sets maxsteps
1791 .  -ts_final_time <maxtime> - Sets maxtime
1792 
1793    Notes:
1794    The default maximum number of iterations is 5000. Default time is 5.0
1795 
1796    Level: intermediate
1797 
1798 .keywords: TS, timestep, set, maximum, iterations
1799 
1800 .seealso: TSSetExactFinalTime()
1801 @*/
1802 PetscErrorCode  TSSetDuration(TS ts,PetscInt maxsteps,PetscReal maxtime)
1803 {
1804   PetscFunctionBegin;
1805   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
1806   PetscValidLogicalCollectiveInt(ts,maxsteps,2);
1807   PetscValidLogicalCollectiveReal(ts,maxtime,2);
1808   if (maxsteps >= 0) ts->max_steps = maxsteps;
1809   if (maxtime != PETSC_DEFAULT) ts->max_time  = maxtime;
1810   PetscFunctionReturn(0);
1811 }
1812 
1813 #undef __FUNCT__
1814 #define __FUNCT__ "TSSetSolution"
1815 /*@
1816    TSSetSolution - Sets the initial solution vector
1817    for use by the TS routines.
1818 
1819    Logically Collective on TS and Vec
1820 
1821    Input Parameters:
1822 +  ts - the TS context obtained from TSCreate()
1823 -  u - the solution vector
1824 
1825    Level: beginner
1826 
1827 .keywords: TS, timestep, set, solution, initial conditions
1828 @*/
1829 PetscErrorCode  TSSetSolution(TS ts,Vec u)
1830 {
1831   PetscErrorCode ierr;
1832   DM             dm;
1833 
1834   PetscFunctionBegin;
1835   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
1836   PetscValidHeaderSpecific(u,VEC_CLASSID,2);
1837   ierr = PetscObjectReference((PetscObject)u);CHKERRQ(ierr);
1838   ierr = VecDestroy(&ts->vec_sol);CHKERRQ(ierr);
1839   ts->vec_sol = u;
1840   ierr = TSGetDM(ts,&dm);CHKERRQ(ierr);
1841   ierr = DMShellSetGlobalVector(dm,u);CHKERRQ(ierr);
1842   PetscFunctionReturn(0);
1843 }
1844 
1845 #undef __FUNCT__
1846 #define __FUNCT__ "TSSetPreStep"
1847 /*@C
1848   TSSetPreStep - Sets the general-purpose function
1849   called once at the beginning of each time step.
1850 
1851   Logically Collective on TS
1852 
1853   Input Parameters:
1854 + ts   - The TS context obtained from TSCreate()
1855 - func - The function
1856 
1857   Calling sequence of func:
1858 . func (TS ts);
1859 
1860   Level: intermediate
1861 
1862   Note:
1863   If a step is rejected, TSStep() will call this routine again before each attempt.
1864   The last completed time step number can be queried using TSGetTimeStepNumber(), the
1865   size of the step being attempted can be obtained using TSGetTimeStep().
1866 
1867 .keywords: TS, timestep
1868 .seealso: TSSetPreStage(), TSSetPostStep(), TSStep()
1869 @*/
1870 PetscErrorCode  TSSetPreStep(TS ts, PetscErrorCode (*func)(TS))
1871 {
1872   PetscFunctionBegin;
1873   PetscValidHeaderSpecific(ts, TS_CLASSID,1);
1874   ts->ops->prestep = func;
1875   PetscFunctionReturn(0);
1876 }
1877 
1878 #undef __FUNCT__
1879 #define __FUNCT__ "TSPreStep"
1880 /*@
1881   TSPreStep - Runs the user-defined pre-step function.
1882 
1883   Collective on TS
1884 
1885   Input Parameters:
1886 . ts   - The TS context obtained from TSCreate()
1887 
1888   Notes:
1889   TSPreStep() is typically used within time stepping implementations,
1890   so most users would not generally call this routine themselves.
1891 
1892   Level: developer
1893 
1894 .keywords: TS, timestep
1895 .seealso: TSSetPreStep(), TSPreStage(), TSPostStep()
1896 @*/
1897 PetscErrorCode  TSPreStep(TS ts)
1898 {
1899   PetscErrorCode ierr;
1900 
1901   PetscFunctionBegin;
1902   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
1903   if (ts->ops->prestep) {
1904     PetscStackPush("TS PreStep function");
1905     ierr = (*ts->ops->prestep)(ts);CHKERRQ(ierr);
1906     PetscStackPop;
1907   }
1908   PetscFunctionReturn(0);
1909 }
1910 
1911 #undef __FUNCT__
1912 #define __FUNCT__ "TSSetPreStage"
1913 /*@C
1914   TSSetPreStage - Sets the general-purpose function
1915   called once at the beginning of each stage.
1916 
1917   Logically Collective on TS
1918 
1919   Input Parameters:
1920 + ts   - The TS context obtained from TSCreate()
1921 - func - The function
1922 
1923   Calling sequence of func:
1924 . PetscErrorCode func(TS ts, PetscReal stagetime);
1925 
1926   Level: intermediate
1927 
1928   Note:
1929   There may be several stages per time step. If the solve for a given stage fails, the step may be rejected and retried.
1930   The time step number being computed can be queried using TSGetTimeStepNumber() and the total size of the step being
1931   attempted can be obtained using TSGetTimeStep(). The time at the start of the step is available via TSGetTime().
1932 
1933 .keywords: TS, timestep
1934 .seealso: TSSetPreStep(), TSSetPostStep(), TSGetApplicationContext()
1935 @*/
1936 PetscErrorCode  TSSetPreStage(TS ts, PetscErrorCode (*func)(TS,PetscReal))
1937 {
1938   PetscFunctionBegin;
1939   PetscValidHeaderSpecific(ts, TS_CLASSID,1);
1940   ts->ops->prestage = func;
1941   PetscFunctionReturn(0);
1942 }
1943 
1944 #undef __FUNCT__
1945 #define __FUNCT__ "TSPreStage"
1946 /*@
1947   TSPreStage - Runs the user-defined pre-stage function set using TSSetPreStage()
1948 
1949   Collective on TS
1950 
1951   Input Parameters:
1952 . ts   - The TS context obtained from TSCreate()
1953 
1954   Notes:
1955   TSPreStage() is typically used within time stepping implementations,
1956   most users would not generally call this routine themselves.
1957 
1958   Level: developer
1959 
1960 .keywords: TS, timestep
1961 .seealso: TSSetPreStep(), TSPreStep(), TSPostStep()
1962 @*/
1963 PetscErrorCode  TSPreStage(TS ts, PetscReal stagetime)
1964 {
1965   PetscErrorCode ierr;
1966 
1967   PetscFunctionBegin;
1968   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
1969   if (ts->ops->prestage) {
1970     PetscStackPush("TS PreStage function");
1971     ierr = (*ts->ops->prestage)(ts,stagetime);CHKERRQ(ierr);
1972     PetscStackPop;
1973   }
1974   PetscFunctionReturn(0);
1975 }
1976 
1977 #undef __FUNCT__
1978 #define __FUNCT__ "TSSetPostStep"
1979 /*@C
1980   TSSetPostStep - Sets the general-purpose function
1981   called once at the end of each time step.
1982 
1983   Logically Collective on TS
1984 
1985   Input Parameters:
1986 + ts   - The TS context obtained from TSCreate()
1987 - func - The function
1988 
1989   Calling sequence of func:
1990 $ func (TS ts);
1991 
1992   Level: intermediate
1993 
1994 .keywords: TS, timestep
1995 .seealso: TSSetPreStep(), TSSetPreStage(), TSGetTimeStep(), TSGetTimeStepNumber(), TSGetTime()
1996 @*/
1997 PetscErrorCode  TSSetPostStep(TS ts, PetscErrorCode (*func)(TS))
1998 {
1999   PetscFunctionBegin;
2000   PetscValidHeaderSpecific(ts, TS_CLASSID,1);
2001   ts->ops->poststep = func;
2002   PetscFunctionReturn(0);
2003 }
2004 
2005 #undef __FUNCT__
2006 #define __FUNCT__ "TSPostStep"
2007 /*@
2008   TSPostStep - Runs the user-defined post-step function.
2009 
2010   Collective on TS
2011 
2012   Input Parameters:
2013 . ts   - The TS context obtained from TSCreate()
2014 
2015   Notes:
2016   TSPostStep() is typically used within time stepping implementations,
2017   so most users would not generally call this routine themselves.
2018 
2019   Level: developer
2020 
2021 .keywords: TS, timestep
2022 @*/
2023 PetscErrorCode  TSPostStep(TS ts)
2024 {
2025   PetscErrorCode ierr;
2026 
2027   PetscFunctionBegin;
2028   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
2029   if (ts->ops->poststep) {
2030     PetscStackPush("TS PostStep function");
2031     ierr = (*ts->ops->poststep)(ts);CHKERRQ(ierr);
2032     PetscStackPop;
2033   }
2034   PetscFunctionReturn(0);
2035 }
2036 
2037 /* ------------ Routines to set performance monitoring options ----------- */
2038 
2039 #undef __FUNCT__
2040 #define __FUNCT__ "TSMonitorSet"
2041 /*@C
2042    TSMonitorSet - Sets an ADDITIONAL function that is to be used at every
2043    timestep to display the iteration's  progress.
2044 
2045    Logically Collective on TS
2046 
2047    Input Parameters:
2048 +  ts - the TS context obtained from TSCreate()
2049 .  monitor - monitoring routine
2050 .  mctx - [optional] user-defined context for private data for the
2051              monitor routine (use PETSC_NULL if no context is desired)
2052 -  monitordestroy - [optional] routine that frees monitor context
2053           (may be PETSC_NULL)
2054 
2055    Calling sequence of monitor:
2056 $    int monitor(TS ts,PetscInt steps,PetscReal time,Vec u,void *mctx)
2057 
2058 +    ts - the TS context
2059 .    steps - iteration number (after the final time step the monitor routine is called with a step of -1, this is at the final time which may have
2060                                been interpolated to)
2061 .    time - current time
2062 .    u - current iterate
2063 -    mctx - [optional] monitoring context
2064 
2065    Notes:
2066    This routine adds an additional monitor to the list of monitors that
2067    already has been loaded.
2068 
2069    Fortran notes: Only a single monitor function can be set for each TS object
2070 
2071    Level: intermediate
2072 
2073 .keywords: TS, timestep, set, monitor
2074 
2075 .seealso: TSMonitorDefault(), TSMonitorCancel()
2076 @*/
2077 PetscErrorCode  TSMonitorSet(TS ts,PetscErrorCode (*monitor)(TS,PetscInt,PetscReal,Vec,void*),void *mctx,PetscErrorCode (*mdestroy)(void**))
2078 {
2079   PetscFunctionBegin;
2080   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
2081   if (ts->numbermonitors >= MAXTSMONITORS) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Too many monitors set");
2082   ts->monitor[ts->numbermonitors]           = monitor;
2083   ts->monitordestroy[ts->numbermonitors]    = mdestroy;
2084   ts->monitorcontext[ts->numbermonitors++]  = (void*)mctx;
2085   PetscFunctionReturn(0);
2086 }
2087 
2088 #undef __FUNCT__
2089 #define __FUNCT__ "TSMonitorCancel"
2090 /*@C
2091    TSMonitorCancel - Clears all the monitors that have been set on a time-step object.
2092 
2093    Logically Collective on TS
2094 
2095    Input Parameters:
2096 .  ts - the TS context obtained from TSCreate()
2097 
2098    Notes:
2099    There is no way to remove a single, specific monitor.
2100 
2101    Level: intermediate
2102 
2103 .keywords: TS, timestep, set, monitor
2104 
2105 .seealso: TSMonitorDefault(), TSMonitorSet()
2106 @*/
2107 PetscErrorCode  TSMonitorCancel(TS ts)
2108 {
2109   PetscErrorCode ierr;
2110   PetscInt       i;
2111 
2112   PetscFunctionBegin;
2113   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
2114   for (i=0; i<ts->numbermonitors; i++) {
2115     if (ts->monitordestroy[i]) {
2116       ierr = (*ts->monitordestroy[i])(&ts->monitorcontext[i]);CHKERRQ(ierr);
2117     }
2118   }
2119   ts->numbermonitors = 0;
2120   PetscFunctionReturn(0);
2121 }
2122 
2123 #undef __FUNCT__
2124 #define __FUNCT__ "TSMonitorDefault"
2125 /*@
2126    TSMonitorDefault - Sets the Default monitor
2127 
2128    Level: intermediate
2129 
2130 .keywords: TS, set, monitor
2131 
2132 .seealso: TSMonitorDefault(), TSMonitorSet()
2133 @*/
2134 PetscErrorCode TSMonitorDefault(TS ts,PetscInt step,PetscReal ptime,Vec v,void *dummy)
2135 {
2136   PetscErrorCode ierr;
2137   PetscViewer    viewer = dummy ? (PetscViewer) dummy : PETSC_VIEWER_STDOUT_(((PetscObject)ts)->comm);
2138 
2139   PetscFunctionBegin;
2140   ierr = PetscViewerASCIIAddTab(viewer,((PetscObject)ts)->tablevel);CHKERRQ(ierr);
2141   ierr = PetscViewerASCIIPrintf(viewer,"%D TS dt %g time %g\n",step,(double)ts->time_step,(double)ptime);CHKERRQ(ierr);
2142   ierr = PetscViewerASCIISubtractTab(viewer,((PetscObject)ts)->tablevel);CHKERRQ(ierr);
2143   PetscFunctionReturn(0);
2144 }
2145 
2146 #undef __FUNCT__
2147 #define __FUNCT__ "TSSetRetainStages"
2148 /*@
2149    TSSetRetainStages - Request that all stages in the upcoming step be stored so that interpolation will be available.
2150 
2151    Logically Collective on TS
2152 
2153    Input Argument:
2154 .  ts - time stepping context
2155 
2156    Output Argument:
2157 .  flg - PETSC_TRUE or PETSC_FALSE
2158 
2159    Level: intermediate
2160 
2161 .keywords: TS, set
2162 
2163 .seealso: TSInterpolate(), TSSetPostStep()
2164 @*/
2165 PetscErrorCode TSSetRetainStages(TS ts,PetscBool flg)
2166 {
2167   PetscFunctionBegin;
2168   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
2169   ts->retain_stages = flg;
2170   PetscFunctionReturn(0);
2171 }
2172 
2173 #undef __FUNCT__
2174 #define __FUNCT__ "TSInterpolate"
2175 /*@
2176    TSInterpolate - Interpolate the solution computed during the previous step to an arbitrary location in the interval
2177 
2178    Collective on TS
2179 
2180    Input Argument:
2181 +  ts - time stepping context
2182 -  t - time to interpolate to
2183 
2184    Output Argument:
2185 .  U - state at given time
2186 
2187    Notes:
2188    The user should call TSSetRetainStages() before taking a step in which interpolation will be requested.
2189 
2190    Level: intermediate
2191 
2192    Developer Notes:
2193    TSInterpolate() and the storing of previous steps/stages should be generalized to support delay differential equations and continuous adjoints.
2194 
2195 .keywords: TS, set
2196 
2197 .seealso: TSSetRetainStages(), TSSetPostStep()
2198 @*/
2199 PetscErrorCode TSInterpolate(TS ts,PetscReal t,Vec U)
2200 {
2201   PetscErrorCode ierr;
2202 
2203   PetscFunctionBegin;
2204   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
2205   if (t < ts->ptime - ts->time_step_prev || t > ts->ptime) SETERRQ3(((PetscObject)ts)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Requested time %G not in last time steps [%G,%G]",t,ts->ptime-ts->time_step_prev,ts->ptime);
2206   if (!ts->ops->interpolate) SETERRQ1(((PetscObject)ts)->comm,PETSC_ERR_SUP,"%s does not provide interpolation",((PetscObject)ts)->type_name);
2207   ierr = (*ts->ops->interpolate)(ts,t,U);CHKERRQ(ierr);
2208   PetscFunctionReturn(0);
2209 }
2210 
2211 #undef __FUNCT__
2212 #define __FUNCT__ "TSStep"
2213 /*@
2214    TSStep - Steps one time step
2215 
2216    Collective on TS
2217 
2218    Input Parameter:
2219 .  ts - the TS context obtained from TSCreate()
2220 
2221    Level: intermediate
2222 
2223    Notes:
2224    The hook set using TSSetPreStep() is called before each attempt to take the step. In general, the time step size may
2225    be changed due to adaptive error controller or solve failures. Note that steps may contain multiple stages.
2226 
2227    This may over-step the final time provided in TSSetDuration() depending on the time-step used. TSSolve() interpolates to exactly the
2228    time provided in TSSetDuration(). One can use TSInterpolate() to determine an interpolated solution within the final timestep.
2229 
2230 .keywords: TS, timestep, solve
2231 
2232 .seealso: TSCreate(), TSSetUp(), TSDestroy(), TSSolve(), TSSetPreStep(), TSSetPreStage(), TSInterpolate()
2233 @*/
2234 PetscErrorCode  TSStep(TS ts)
2235 {
2236   PetscReal      ptime_prev;
2237   PetscErrorCode ierr;
2238 
2239   PetscFunctionBegin;
2240   PetscValidHeaderSpecific(ts, TS_CLASSID,1);
2241   ierr = TSSetUp(ts);CHKERRQ(ierr);
2242 
2243   ts->reason = TS_CONVERGED_ITERATING;
2244 
2245   ptime_prev = ts->ptime;
2246   ierr = PetscLogEventBegin(TS_Step,ts,0,0,0);CHKERRQ(ierr);
2247   ierr = (*ts->ops->step)(ts);CHKERRQ(ierr);
2248   ierr = PetscLogEventEnd(TS_Step,ts,0,0,0);CHKERRQ(ierr);
2249   ts->time_step_prev = ts->ptime - ptime_prev;
2250 
2251   if (ts->reason < 0) {
2252     if (ts->errorifstepfailed) {
2253       if (ts->reason == TS_DIVERGED_NONLINEAR_SOLVE) {
2254         SETERRQ1(((PetscObject)ts)->comm,PETSC_ERR_NOT_CONVERGED,"TSStep has failed due to %s, increase -ts_max_snes_failures or make negative to attempt recovery",TSConvergedReasons[ts->reason]);
2255       } else SETERRQ1(((PetscObject)ts)->comm,PETSC_ERR_NOT_CONVERGED,"TSStep has failed due to %s",TSConvergedReasons[ts->reason]);
2256     }
2257   } else if (!ts->reason) {
2258     if (ts->steps >= ts->max_steps)
2259       ts->reason = TS_CONVERGED_ITS;
2260     else if (ts->ptime >= ts->max_time)
2261       ts->reason = TS_CONVERGED_TIME;
2262   }
2263 
2264   PetscFunctionReturn(0);
2265 }
2266 
2267 #undef __FUNCT__
2268 #define __FUNCT__ "TSEvaluateStep"
2269 /*@
2270    TSEvaluateStep - Evaluate the solution at the end of a time step with a given order of accuracy.
2271 
2272    Collective on TS
2273 
2274    Input Arguments:
2275 +  ts - time stepping context
2276 .  order - desired order of accuracy
2277 -  done - whether the step was evaluated at this order (pass PETSC_NULL to generate an error if not available)
2278 
2279    Output Arguments:
2280 .  U - state at the end of the current step
2281 
2282    Level: advanced
2283 
2284    Notes:
2285    This function cannot be called until all stages have been evaluated.
2286    It is normally called by adaptive controllers before a step has been accepted and may also be called by the user after TSStep() has returned.
2287 
2288 .seealso: TSStep(), TSAdapt
2289 @*/
2290 PetscErrorCode TSEvaluateStep(TS ts,PetscInt order,Vec U,PetscBool *done)
2291 {
2292   PetscErrorCode ierr;
2293 
2294   PetscFunctionBegin;
2295   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
2296   PetscValidType(ts,1);
2297   PetscValidHeaderSpecific(U,VEC_CLASSID,3);
2298   if (!ts->ops->evaluatestep) SETERRQ1(((PetscObject)ts)->comm,PETSC_ERR_SUP,"TSEvaluateStep not implemented for type '%s'",((PetscObject)ts)->type_name);
2299   ierr = (*ts->ops->evaluatestep)(ts,order,U,done);CHKERRQ(ierr);
2300   PetscFunctionReturn(0);
2301 }
2302 
2303 #undef __FUNCT__
2304 #define __FUNCT__ "TSSolve"
2305 /*@
2306    TSSolve - Steps the requested number of timesteps.
2307 
2308    Collective on TS
2309 
2310    Input Parameter:
2311 +  ts - the TS context obtained from TSCreate()
2312 -  u - the solution vector  (can be null if TSSetSolution() was used, otherwise must contain the initial conditions)
2313 
2314    Level: beginner
2315 
2316    Notes:
2317    The final time returned by this function may be different from the time of the internally
2318    held state accessible by TSGetSolution() and TSGetTime() because the method may have
2319    stepped over the final time.
2320 
2321 .keywords: TS, timestep, solve
2322 
2323 .seealso: TSCreate(), TSSetSolution(), TSStep()
2324 @*/
2325 PetscErrorCode TSSolve(TS ts,Vec u)
2326 {
2327   PetscBool      flg;
2328   char           filename[PETSC_MAX_PATH_LEN];
2329   PetscViewer    viewer;
2330   PetscErrorCode ierr;
2331 
2332   PetscFunctionBegin;
2333   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
2334   if (u) PetscValidHeaderSpecific(u,VEC_CLASSID,2);
2335   if (ts->exact_final_time == TS_EXACTFINALTIME_INTERPOLATE) {   /* Need ts->vec_sol to be distinct so it is not overwritten when we interpolate at the end */
2336     if (!ts->vec_sol || u == ts->vec_sol) {
2337       Vec y;
2338       ierr = VecDuplicate(u,&y);CHKERRQ(ierr);
2339       ierr = TSSetSolution(ts,y);CHKERRQ(ierr);
2340       ierr = VecDestroy(&y);CHKERRQ(ierr); /* grant ownership */
2341     }
2342     if (u) {
2343       ierr = VecCopy(u,ts->vec_sol);CHKERRQ(ierr);
2344     }
2345   } else {
2346     if (u) {
2347       ierr = TSSetSolution(ts,u);CHKERRQ(ierr);
2348     }
2349   }
2350   ierr = TSSetUp(ts);CHKERRQ(ierr);
2351   /* reset time step and iteration counters */
2352   ts->steps = 0;
2353   ts->ksp_its = 0;
2354   ts->snes_its = 0;
2355   ts->num_snes_failures = 0;
2356   ts->reject = 0;
2357   ts->reason = TS_CONVERGED_ITERATING;
2358 
2359   if (ts->ops->solve) {         /* This private interface is transitional and should be removed when all implementations are updated. */
2360     ierr = (*ts->ops->solve)(ts);CHKERRQ(ierr);
2361     ierr = VecCopy(ts->vec_sol,u);CHKERRQ(ierr);
2362     ts->solvetime = ts->ptime;
2363   } else {
2364     /* steps the requested number of timesteps. */
2365     ierr = TSMonitor(ts,ts->steps,ts->ptime,ts->vec_sol);CHKERRQ(ierr);
2366     if (ts->steps >= ts->max_steps)
2367       ts->reason = TS_CONVERGED_ITS;
2368     else if (ts->ptime >= ts->max_time)
2369       ts->reason = TS_CONVERGED_TIME;
2370     while (!ts->reason) {
2371       ierr = TSStep(ts);CHKERRQ(ierr);
2372       ierr = TSPostStep(ts);CHKERRQ(ierr);
2373       ierr = TSMonitor(ts,ts->steps,ts->ptime,ts->vec_sol);CHKERRQ(ierr);
2374     }
2375     if (ts->exact_final_time == TS_EXACTFINALTIME_INTERPOLATE && ts->ptime > ts->max_time) {
2376       ierr = TSInterpolate(ts,ts->max_time,u);CHKERRQ(ierr);
2377       ts->solvetime = ts->max_time;
2378     } else {
2379       if (u) {ierr = VecCopy(ts->vec_sol,u);CHKERRQ(ierr);}
2380       ts->solvetime = ts->ptime;
2381     }
2382   }
2383   ierr = TSMonitor(ts,-1,ts->ptime,ts->vec_sol);CHKERRQ(ierr);
2384   ierr = PetscOptionsGetString(((PetscObject)ts)->prefix,"-ts_view",filename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr);
2385   if (flg && !PetscPreLoadingOn) {
2386     ierr = PetscViewerASCIIOpen(((PetscObject)ts)->comm,filename,&viewer);CHKERRQ(ierr);
2387     ierr = TSView(ts,viewer);CHKERRQ(ierr);
2388     ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr);
2389   }
2390   flg = PETSC_FALSE;
2391   ierr = PetscOptionsGetBool(((PetscObject)ts)->prefix,"-ts_view_draw",&flg,PETSC_NULL);CHKERRQ(ierr);
2392   if (flg) {
2393     ierr = PetscViewerDrawOpen(((PetscObject)ts)->comm,PETSC_NULL,"TS Solver",0,0,600,600,&viewer);CHKERRQ(ierr);
2394     ierr = TSView(ts,viewer);CHKERRQ(ierr);
2395     ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr);
2396   }
2397   PetscFunctionReturn(0);
2398 }
2399 
2400 #undef __FUNCT__
2401 #define __FUNCT__ "TSMonitor"
2402 /*@
2403    TSMonitor - Runs all user-provided monitor routines set using TSMonitorSet()
2404 
2405    Collective on TS
2406 
2407    Input Parameters:
2408 +  ts - time stepping context obtained from TSCreate()
2409 .  step - step number that has just completed
2410 .  ptime - model time of the state
2411 -  u - state at the current model time
2412 
2413    Notes:
2414    TSMonitor() is typically used within the time stepping implementations.
2415    Users might call this function when using the TSStep() interface instead of TSSolve().
2416 
2417    Level: advanced
2418 
2419 .keywords: TS, timestep
2420 @*/
2421 PetscErrorCode TSMonitor(TS ts,PetscInt step,PetscReal ptime,Vec u)
2422 {
2423   PetscErrorCode ierr;
2424   PetscInt       i,n = ts->numbermonitors;
2425 
2426   PetscFunctionBegin;
2427   for (i=0; i<n; i++) {
2428     ierr = (*ts->monitor[i])(ts,step,ptime,u,ts->monitorcontext[i]);CHKERRQ(ierr);
2429   }
2430   PetscFunctionReturn(0);
2431 }
2432 
2433 /* ------------------------------------------------------------------------*/
2434 struct _n_TSMonitorLGCtx {
2435   PetscDrawLG lg;
2436   PetscInt    howoften;  /* when > 0 uses step % howoften, when negative only final solution plotted */
2437   PetscInt    ksp_its,snes_its;
2438 };
2439 
2440 
2441 #undef __FUNCT__
2442 #define __FUNCT__ "TSMonitorLGCtxCreate"
2443 /*@C
2444    TSMonitorLGCtxCreate - Creates a line graph context for use with
2445    TS to monitor the solution process graphically in various ways
2446 
2447    Collective on TS
2448 
2449    Input Parameters:
2450 +  host - the X display to open, or null for the local machine
2451 .  label - the title to put in the title bar
2452 .  x, y - the screen coordinates of the upper left coordinate of the window
2453 .  m, n - the screen width and height in pixels
2454 -  howoften - if positive then determines the frequency of the plotting, if -1 then only at the final time
2455 
2456    Output Parameter:
2457 .  ctx - the context
2458 
2459    Options Database Key:
2460 +  -ts_monitor_lg_timestep - automatically sets line graph monitor
2461 .  -ts_monitor_lg_solution -
2462 .  -ts_monitor_lg_error -
2463 .  -ts_monitor_lg_ksp_iterations -
2464 .  -ts_monitor_lg_snes_iterations -
2465 -  -lg_indicate_data_points <true,false> - indicate the data points (at each time step) on the plot; default is true
2466 
2467    Notes:
2468    Use TSMonitorLGCtxDestroy() to destroy.
2469 
2470    Level: intermediate
2471 
2472 .keywords: TS, monitor, line graph, residual, seealso
2473 
2474 .seealso: TSMonitorLGTimeStep(), TSMonitorSet(), TSMonitorLGSolution(), TSMonitorLGError()
2475 
2476 @*/
2477 PetscErrorCode  TSMonitorLGCtxCreate(MPI_Comm comm,const char host[],const char label[],int x,int y,int m,int n,PetscInt howoften,TSMonitorLGCtx *ctx)
2478 {
2479   PetscDraw      win;
2480   PetscErrorCode ierr;
2481   PetscBool      flg = PETSC_TRUE;
2482 
2483   PetscFunctionBegin;
2484   ierr = PetscNew(struct _n_TSMonitorLGCtx,ctx);CHKERRQ(ierr);
2485   ierr = PetscDrawCreate(comm,host,label,x,y,m,n,&win);CHKERRQ(ierr);
2486   ierr = PetscDrawSetFromOptions(win);CHKERRQ(ierr);
2487   ierr = PetscDrawLGCreate(win,1,&(*ctx)->lg);CHKERRQ(ierr);
2488   ierr = PetscOptionsGetBool(PETSC_NULL,"-lg_indicate_data_points",&flg,PETSC_NULL);CHKERRQ(ierr);
2489   if (flg) {
2490     ierr = PetscDrawLGIndicateDataPoints((*ctx)->lg);CHKERRQ(ierr);
2491   }
2492   ierr = PetscLogObjectParent((*ctx)->lg,win);CHKERRQ(ierr);
2493   (*ctx)->howoften = howoften;
2494   PetscFunctionReturn(0);
2495 }
2496 
2497 #undef __FUNCT__
2498 #define __FUNCT__ "TSMonitorLGTimeStep"
2499 PetscErrorCode TSMonitorLGTimeStep(TS ts,PetscInt n,PetscReal ptime,Vec v,void *monctx)
2500 {
2501   TSMonitorLGCtx ctx = (TSMonitorLGCtx) monctx;
2502   PetscReal      x = ptime,y;
2503   PetscErrorCode ierr;
2504 
2505   PetscFunctionBegin;
2506   if (!n) {
2507     PetscDrawAxis  axis;
2508     ierr = PetscDrawLGGetAxis(ctx->lg,&axis);CHKERRQ(ierr);
2509     ierr = PetscDrawAxisSetLabels(axis,"Timestep as function of time","Time","Time step");CHKERRQ(ierr);
2510     ierr = PetscDrawLGReset(ctx->lg);CHKERRQ(ierr);
2511   }
2512   ierr = TSGetTimeStep(ts,&y);CHKERRQ(ierr);
2513   ierr = PetscDrawLGAddPoint(ctx->lg,&x,&y);CHKERRQ(ierr);
2514   if (((ctx->howoften > 0) && (!(n % ctx->howoften))) || ((ctx->howoften == -1) && (n == -1))){
2515     ierr = PetscDrawLGDraw(ctx->lg);CHKERRQ(ierr);
2516   }
2517   PetscFunctionReturn(0);
2518 }
2519 
2520 #undef __FUNCT__
2521 #define __FUNCT__ "TSMonitorLGCtxDestroy"
2522 /*@C
2523    TSMonitorLGCtxDestroy - Destroys a line graph context that was created
2524    with TSMonitorLGCtxCreate().
2525 
2526    Collective on TSMonitorLGCtx
2527 
2528    Input Parameter:
2529 .  ctx - the monitor context
2530 
2531    Level: intermediate
2532 
2533 .keywords: TS, monitor, line graph, destroy
2534 
2535 .seealso: TSMonitorLGCtxCreate(),  TSMonitorSet(), TSMonitorLGTimeStep();
2536 @*/
2537 PetscErrorCode  TSMonitorLGCtxDestroy(TSMonitorLGCtx *ctx)
2538 {
2539   PetscDraw      draw;
2540   PetscErrorCode ierr;
2541 
2542   PetscFunctionBegin;
2543   ierr = PetscDrawLGGetDraw((*ctx)->lg,&draw);CHKERRQ(ierr);
2544   ierr = PetscDrawDestroy(&draw);CHKERRQ(ierr);
2545   ierr = PetscDrawLGDestroy(&(*ctx)->lg);CHKERRQ(ierr);
2546   ierr = PetscFree(*ctx);CHKERRQ(ierr);
2547   PetscFunctionReturn(0);
2548 }
2549 
2550 #undef __FUNCT__
2551 #define __FUNCT__ "TSGetTime"
2552 /*@
2553    TSGetTime - Gets the time of the most recently completed step.
2554 
2555    Not Collective
2556 
2557    Input Parameter:
2558 .  ts - the TS context obtained from TSCreate()
2559 
2560    Output Parameter:
2561 .  t  - the current time
2562 
2563    Level: beginner
2564 
2565    Note:
2566    When called during time step evaluation (e.g. during residual evaluation or via hooks set using TSSetPreStep(),
2567    TSSetPreStage(), or TSSetPostStep()), the time is the time at the start of the step being evaluated.
2568 
2569 .seealso: TSSetInitialTimeStep(), TSGetTimeStep()
2570 
2571 .keywords: TS, get, time
2572 @*/
2573 PetscErrorCode  TSGetTime(TS ts,PetscReal* t)
2574 {
2575   PetscFunctionBegin;
2576   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
2577   PetscValidRealPointer(t,2);
2578   *t = ts->ptime;
2579   PetscFunctionReturn(0);
2580 }
2581 
2582 #undef __FUNCT__
2583 #define __FUNCT__ "TSSetTime"
2584 /*@
2585    TSSetTime - Allows one to reset the time.
2586 
2587    Logically Collective on TS
2588 
2589    Input Parameters:
2590 +  ts - the TS context obtained from TSCreate()
2591 -  time - the time
2592 
2593    Level: intermediate
2594 
2595 .seealso: TSGetTime(), TSSetDuration()
2596 
2597 .keywords: TS, set, time
2598 @*/
2599 PetscErrorCode  TSSetTime(TS ts, PetscReal t)
2600 {
2601   PetscFunctionBegin;
2602   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
2603   PetscValidLogicalCollectiveReal(ts,t,2);
2604   ts->ptime = t;
2605   PetscFunctionReturn(0);
2606 }
2607 
2608 #undef __FUNCT__
2609 #define __FUNCT__ "TSSetOptionsPrefix"
2610 /*@C
2611    TSSetOptionsPrefix - Sets the prefix used for searching for all
2612    TS options in the database.
2613 
2614    Logically Collective on TS
2615 
2616    Input Parameter:
2617 +  ts     - The TS context
2618 -  prefix - The prefix to prepend to all option names
2619 
2620    Notes:
2621    A hyphen (-) must NOT be given at the beginning of the prefix name.
2622    The first character of all runtime options is AUTOMATICALLY the
2623    hyphen.
2624 
2625    Level: advanced
2626 
2627 .keywords: TS, set, options, prefix, database
2628 
2629 .seealso: TSSetFromOptions()
2630 
2631 @*/
2632 PetscErrorCode  TSSetOptionsPrefix(TS ts,const char prefix[])
2633 {
2634   PetscErrorCode ierr;
2635   SNES           snes;
2636 
2637   PetscFunctionBegin;
2638   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
2639   ierr = PetscObjectSetOptionsPrefix((PetscObject)ts,prefix);CHKERRQ(ierr);
2640   ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr);
2641   ierr = SNESSetOptionsPrefix(snes,prefix);CHKERRQ(ierr);
2642   PetscFunctionReturn(0);
2643 }
2644 
2645 
2646 #undef __FUNCT__
2647 #define __FUNCT__ "TSAppendOptionsPrefix"
2648 /*@C
2649    TSAppendOptionsPrefix - Appends to the prefix used for searching for all
2650    TS options in the database.
2651 
2652    Logically Collective on TS
2653 
2654    Input Parameter:
2655 +  ts     - The TS context
2656 -  prefix - The prefix to prepend to all option names
2657 
2658    Notes:
2659    A hyphen (-) must NOT be given at the beginning of the prefix name.
2660    The first character of all runtime options is AUTOMATICALLY the
2661    hyphen.
2662 
2663    Level: advanced
2664 
2665 .keywords: TS, append, options, prefix, database
2666 
2667 .seealso: TSGetOptionsPrefix()
2668 
2669 @*/
2670 PetscErrorCode  TSAppendOptionsPrefix(TS ts,const char prefix[])
2671 {
2672   PetscErrorCode ierr;
2673   SNES           snes;
2674 
2675   PetscFunctionBegin;
2676   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
2677   ierr = PetscObjectAppendOptionsPrefix((PetscObject)ts,prefix);CHKERRQ(ierr);
2678   ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr);
2679   ierr = SNESAppendOptionsPrefix(snes,prefix);CHKERRQ(ierr);
2680   PetscFunctionReturn(0);
2681 }
2682 
2683 #undef __FUNCT__
2684 #define __FUNCT__ "TSGetOptionsPrefix"
2685 /*@C
2686    TSGetOptionsPrefix - Sets the prefix used for searching for all
2687    TS options in the database.
2688 
2689    Not Collective
2690 
2691    Input Parameter:
2692 .  ts - The TS context
2693 
2694    Output Parameter:
2695 .  prefix - A pointer to the prefix string used
2696 
2697    Notes: On the fortran side, the user should pass in a string 'prifix' of
2698    sufficient length to hold the prefix.
2699 
2700    Level: intermediate
2701 
2702 .keywords: TS, get, options, prefix, database
2703 
2704 .seealso: TSAppendOptionsPrefix()
2705 @*/
2706 PetscErrorCode  TSGetOptionsPrefix(TS ts,const char *prefix[])
2707 {
2708   PetscErrorCode ierr;
2709 
2710   PetscFunctionBegin;
2711   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
2712   PetscValidPointer(prefix,2);
2713   ierr = PetscObjectGetOptionsPrefix((PetscObject)ts,prefix);CHKERRQ(ierr);
2714   PetscFunctionReturn(0);
2715 }
2716 
2717 #undef __FUNCT__
2718 #define __FUNCT__ "TSGetRHSJacobian"
2719 /*@C
2720    TSGetRHSJacobian - Returns the Jacobian J at the present timestep.
2721 
2722    Not Collective, but parallel objects are returned if TS is parallel
2723 
2724    Input Parameter:
2725 .  ts  - The TS context obtained from TSCreate()
2726 
2727    Output Parameters:
2728 +  J   - The Jacobian J of F, where U_t = G(U,t)
2729 .  M   - The preconditioner matrix, usually the same as J
2730 .  func - Function to compute the Jacobian of the RHS
2731 -  ctx - User-defined context for Jacobian evaluation routine
2732 
2733    Notes: You can pass in PETSC_NULL for any return argument you do not need.
2734 
2735    Level: intermediate
2736 
2737 .seealso: TSGetTimeStep(), TSGetMatrices(), TSGetTime(), TSGetTimeStepNumber()
2738 
2739 .keywords: TS, timestep, get, matrix, Jacobian
2740 @*/
2741 PetscErrorCode  TSGetRHSJacobian(TS ts,Mat *J,Mat *M,TSRHSJacobian *func,void **ctx)
2742 {
2743   PetscErrorCode ierr;
2744   SNES           snes;
2745   DM             dm;
2746 
2747   PetscFunctionBegin;
2748   ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr);
2749   ierr = SNESGetJacobian(snes,J,M,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);
2750   ierr = TSGetDM(ts,&dm);CHKERRQ(ierr);
2751   ierr = DMTSGetRHSJacobian(dm,func,ctx);CHKERRQ(ierr);
2752   PetscFunctionReturn(0);
2753 }
2754 
2755 #undef __FUNCT__
2756 #define __FUNCT__ "TSGetIJacobian"
2757 /*@C
2758    TSGetIJacobian - Returns the implicit Jacobian at the present timestep.
2759 
2760    Not Collective, but parallel objects are returned if TS is parallel
2761 
2762    Input Parameter:
2763 .  ts  - The TS context obtained from TSCreate()
2764 
2765    Output Parameters:
2766 +  A   - The Jacobian of F(t,U,U_t)
2767 .  B   - The preconditioner matrix, often the same as A
2768 .  f   - The function to compute the matrices
2769 - ctx - User-defined context for Jacobian evaluation routine
2770 
2771    Notes: You can pass in PETSC_NULL for any return argument you do not need.
2772 
2773    Level: advanced
2774 
2775 .seealso: TSGetTimeStep(), TSGetRHSJacobian(), TSGetMatrices(), TSGetTime(), TSGetTimeStepNumber()
2776 
2777 .keywords: TS, timestep, get, matrix, Jacobian
2778 @*/
2779 PetscErrorCode  TSGetIJacobian(TS ts,Mat *A,Mat *B,TSIJacobian *f,void **ctx)
2780 {
2781   PetscErrorCode ierr;
2782   SNES           snes;
2783   DM             dm;
2784 
2785   PetscFunctionBegin;
2786   ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr);
2787   ierr = SNESSetUpMatrices(snes);CHKERRQ(ierr);
2788   ierr = SNESGetJacobian(snes,A,B,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);
2789   ierr = TSGetDM(ts,&dm);CHKERRQ(ierr);
2790   ierr = DMTSGetIJacobian(dm,f,ctx);CHKERRQ(ierr);
2791   PetscFunctionReturn(0);
2792 }
2793 
2794 struct _n_TSMonitorDrawCtx {
2795   PetscViewer viewer;
2796   Vec         initialsolution;
2797   PetscBool   showinitial;
2798   PetscInt    howoften;  /* when > 0 uses step % howoften, when negative only final solution plotted */
2799 };
2800 
2801 #undef __FUNCT__
2802 #define __FUNCT__ "TSMonitorDrawSolution"
2803 /*@C
2804    TSMonitorDrawSolution - Monitors progress of the TS solvers by calling
2805    VecView() for the solution at each timestep
2806 
2807    Collective on TS
2808 
2809    Input Parameters:
2810 +  ts - the TS context
2811 .  step - current time-step
2812 .  ptime - current time
2813 -  dummy - either a viewer or PETSC_NULL
2814 
2815    Options Database:
2816 .   -ts_monitor_draw_solution_initial - show initial solution as well as current solution
2817 
2818    Notes: the initial solution and current solution are not displayed with a common axis scaling so generally the option -ts_monitor_draw_solution_initial
2819        will look bad
2820 
2821    Level: intermediate
2822 
2823 .keywords: TS,  vector, monitor, view
2824 
2825 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView()
2826 @*/
2827 PetscErrorCode  TSMonitorDrawSolution(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dummy)
2828 {
2829   PetscErrorCode   ierr;
2830   TSMonitorDrawCtx ictx = (TSMonitorDrawCtx)dummy;
2831 
2832   PetscFunctionBegin;
2833   if (!step && ictx->showinitial) {
2834     if (!ictx->initialsolution) {
2835       ierr = VecDuplicate(u,&ictx->initialsolution);CHKERRQ(ierr);
2836     }
2837     ierr = VecCopy(u,ictx->initialsolution);CHKERRQ(ierr);
2838   }
2839   if (!(((ictx->howoften > 0) && (!(step % ictx->howoften)) && (step > -1)) || ((ictx->howoften == -1) && (step == -1)))) PetscFunctionReturn(0);
2840 
2841   if (ictx->showinitial) {
2842     PetscReal pause;
2843     ierr = PetscViewerDrawGetPause(ictx->viewer,&pause);CHKERRQ(ierr);
2844     ierr = PetscViewerDrawSetPause(ictx->viewer,0.0);CHKERRQ(ierr);
2845     ierr = VecView(ictx->initialsolution,ictx->viewer);CHKERRQ(ierr);
2846     ierr = PetscViewerDrawSetPause(ictx->viewer,pause);CHKERRQ(ierr);
2847     ierr = PetscViewerDrawSetHold(ictx->viewer,PETSC_TRUE);CHKERRQ(ierr);
2848   }
2849   ierr = VecView(u,ictx->viewer);CHKERRQ(ierr);
2850   if (ictx->showinitial) {
2851     ierr = PetscViewerDrawSetHold(ictx->viewer,PETSC_FALSE);CHKERRQ(ierr);
2852   }
2853   PetscFunctionReturn(0);
2854 }
2855 
2856 
2857 #undef __FUNCT__
2858 #define __FUNCT__ "TSMonitorDrawCtxDestroy"
2859 /*@C
2860    TSMonitorDrawCtxDestroy - Destroys the monitor context for TSMonitorDrawSolution()
2861 
2862    Collective on TS
2863 
2864    Input Parameters:
2865 .    ctx - the monitor context
2866 
2867    Level: intermediate
2868 
2869 .keywords: TS,  vector, monitor, view
2870 
2871 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorDrawSolution(), TSMonitorDrawError()
2872 @*/
2873 PetscErrorCode  TSMonitorDrawCtxDestroy(TSMonitorDrawCtx *ictx)
2874 {
2875   PetscErrorCode       ierr;
2876 
2877   PetscFunctionBegin;
2878   ierr = PetscViewerDestroy(&(*ictx)->viewer);CHKERRQ(ierr);
2879   ierr = VecDestroy(&(*ictx)->initialsolution);CHKERRQ(ierr);
2880   ierr = PetscFree(*ictx);CHKERRQ(ierr);
2881   PetscFunctionReturn(0);
2882 }
2883 
2884 #undef __FUNCT__
2885 #define __FUNCT__ "TSMonitorDrawCtxCreate"
2886 /*@C
2887    TSMonitorDrawCtxCreate - Creates the monitor context for TSMonitorDrawCtx
2888 
2889    Collective on TS
2890 
2891    Input Parameter:
2892 .    ts - time-step context
2893 
2894    Output Patameter:
2895 .    ctx - the monitor context
2896 
2897    Options Database:
2898 .   -ts_monitor_draw_solution_initial - show initial solution as well as current solution
2899 
2900    Level: intermediate
2901 
2902 .keywords: TS,  vector, monitor, view
2903 
2904 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorDrawCtx()
2905 @*/
2906 PetscErrorCode  TSMonitorDrawCtxCreate(MPI_Comm comm,const char host[],const char label[],int x,int y,int m,int n,PetscInt howoften,TSMonitorDrawCtx *ctx)
2907 {
2908   PetscErrorCode   ierr;
2909 
2910   PetscFunctionBegin;
2911   ierr = PetscNew(struct _n_TSMonitorDrawCtx,ctx);CHKERRQ(ierr);
2912   ierr = PetscViewerDrawOpen(comm,host,label,x,y,m,n,&(*ctx)->viewer);CHKERRQ(ierr);
2913   (*ctx)->showinitial = PETSC_FALSE;
2914   (*ctx)->howoften    = howoften;
2915   ierr = PetscOptionsGetBool(PETSC_NULL,"-ts_monitor_draw_solution_initial",&(*ctx)->showinitial,PETSC_NULL);CHKERRQ(ierr);
2916   PetscFunctionReturn(0);
2917 }
2918 
2919 #undef __FUNCT__
2920 #define __FUNCT__ "TSMonitorDrawError"
2921 /*@C
2922    TSMonitorDrawError - Monitors progress of the TS solvers by calling
2923    VecView() for the error at each timestep
2924 
2925    Collective on TS
2926 
2927    Input Parameters:
2928 +  ts - the TS context
2929 .  step - current time-step
2930 .  ptime - current time
2931 -  dummy - either a viewer or PETSC_NULL
2932 
2933    Level: intermediate
2934 
2935 .keywords: TS,  vector, monitor, view
2936 
2937 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView()
2938 @*/
2939 PetscErrorCode  TSMonitorDrawError(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dummy)
2940 {
2941   PetscErrorCode   ierr;
2942   TSMonitorDrawCtx ctx = (TSMonitorDrawCtx)dummy;
2943   PetscViewer      viewer = ctx->viewer;
2944   Vec              work;
2945 
2946   PetscFunctionBegin;
2947   if (!(((ctx->howoften > 0) && (!(step % ctx->howoften)) && (step > -1)) || ((ctx->howoften == -1) && (step == -1)))) PetscFunctionReturn(0);
2948   ierr = VecDuplicate(u,&work);CHKERRQ(ierr);
2949   ierr = TSComputeSolutionFunction(ts,ptime,work);CHKERRQ(ierr);
2950   ierr = VecAXPY(work,-1.0,u);CHKERRQ(ierr);
2951   ierr = VecView(work,viewer);CHKERRQ(ierr);
2952   ierr = VecDestroy(&work);CHKERRQ(ierr);
2953   PetscFunctionReturn(0);
2954 }
2955 
2956 #include <petsc-private/dmimpl.h>
2957 #undef __FUNCT__
2958 #define __FUNCT__ "TSSetDM"
2959 /*@
2960    TSSetDM - Sets the DM that may be used by some preconditioners
2961 
2962    Logically Collective on TS and DM
2963 
2964    Input Parameters:
2965 +  ts - the preconditioner context
2966 -  dm - the dm
2967 
2968    Level: intermediate
2969 
2970 
2971 .seealso: TSGetDM(), SNESSetDM(), SNESGetDM()
2972 @*/
2973 PetscErrorCode  TSSetDM(TS ts,DM dm)
2974 {
2975   PetscErrorCode ierr;
2976   SNES           snes;
2977   DMTS           tsdm;
2978 
2979   PetscFunctionBegin;
2980   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
2981   ierr = PetscObjectReference((PetscObject)dm);CHKERRQ(ierr);
2982   if (ts->dm) {               /* Move the DMTS context over to the new DM unless the new DM already has one */
2983     if (ts->dm->dmts && !dm->dmts) {
2984       ierr = DMCopyDMTS(ts->dm,dm);CHKERRQ(ierr);
2985       ierr = DMGetDMTS(ts->dm,&tsdm);CHKERRQ(ierr);
2986       if (tsdm->originaldm == ts->dm) { /* Grant write privileges to the replacement DM */
2987         tsdm->originaldm = dm;
2988       }
2989     }
2990     ierr = DMDestroy(&ts->dm);CHKERRQ(ierr);
2991   }
2992   ts->dm = dm;
2993   ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr);
2994   ierr = SNESSetDM(snes,dm);CHKERRQ(ierr);
2995   PetscFunctionReturn(0);
2996 }
2997 
2998 #undef __FUNCT__
2999 #define __FUNCT__ "TSGetDM"
3000 /*@
3001    TSGetDM - Gets the DM that may be used by some preconditioners
3002 
3003    Not Collective
3004 
3005    Input Parameter:
3006 . ts - the preconditioner context
3007 
3008    Output Parameter:
3009 .  dm - the dm
3010 
3011    Level: intermediate
3012 
3013 
3014 .seealso: TSSetDM(), SNESSetDM(), SNESGetDM()
3015 @*/
3016 PetscErrorCode  TSGetDM(TS ts,DM *dm)
3017 {
3018   PetscErrorCode ierr;
3019 
3020   PetscFunctionBegin;
3021   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
3022   if (!ts->dm) {
3023     ierr = DMShellCreate(((PetscObject)ts)->comm,&ts->dm);CHKERRQ(ierr);
3024     if (ts->snes) {ierr = SNESSetDM(ts->snes,ts->dm);CHKERRQ(ierr);}
3025   }
3026   *dm = ts->dm;
3027   PetscFunctionReturn(0);
3028 }
3029 
3030 #undef __FUNCT__
3031 #define __FUNCT__ "SNESTSFormFunction"
3032 /*@
3033    SNESTSFormFunction - Function to evaluate nonlinear residual
3034 
3035    Logically Collective on SNES
3036 
3037    Input Parameter:
3038 + snes - nonlinear solver
3039 . U - the current state at which to evaluate the residual
3040 - ctx - user context, must be a TS
3041 
3042    Output Parameter:
3043 . F - the nonlinear residual
3044 
3045    Notes:
3046    This function is not normally called by users and is automatically registered with the SNES used by TS.
3047    It is most frequently passed to MatFDColoringSetFunction().
3048 
3049    Level: advanced
3050 
3051 .seealso: SNESSetFunction(), MatFDColoringSetFunction()
3052 @*/
3053 PetscErrorCode  SNESTSFormFunction(SNES snes,Vec U,Vec F,void *ctx)
3054 {
3055   TS             ts = (TS)ctx;
3056   PetscErrorCode ierr;
3057 
3058   PetscFunctionBegin;
3059   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3060   PetscValidHeaderSpecific(U,VEC_CLASSID,2);
3061   PetscValidHeaderSpecific(F,VEC_CLASSID,3);
3062   PetscValidHeaderSpecific(ts,TS_CLASSID,4);
3063   ierr = (ts->ops->snesfunction)(snes,U,F,ts);CHKERRQ(ierr);
3064   PetscFunctionReturn(0);
3065 }
3066 
3067 #undef __FUNCT__
3068 #define __FUNCT__ "SNESTSFormJacobian"
3069 /*@
3070    SNESTSFormJacobian - Function to evaluate the Jacobian
3071 
3072    Collective on SNES
3073 
3074    Input Parameter:
3075 + snes - nonlinear solver
3076 . U - the current state at which to evaluate the residual
3077 - ctx - user context, must be a TS
3078 
3079    Output Parameter:
3080 + A - the Jacobian
3081 . B - the preconditioning matrix (may be the same as A)
3082 - flag - indicates any structure change in the matrix
3083 
3084    Notes:
3085    This function is not normally called by users and is automatically registered with the SNES used by TS.
3086 
3087    Level: developer
3088 
3089 .seealso: SNESSetJacobian()
3090 @*/
3091 PetscErrorCode  SNESTSFormJacobian(SNES snes,Vec U,Mat *A,Mat *B,MatStructure *flag,void *ctx)
3092 {
3093   TS             ts = (TS)ctx;
3094   PetscErrorCode ierr;
3095 
3096   PetscFunctionBegin;
3097   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3098   PetscValidHeaderSpecific(U,VEC_CLASSID,2);
3099   PetscValidPointer(A,3);
3100   PetscValidHeaderSpecific(*A,MAT_CLASSID,3);
3101   PetscValidPointer(B,4);
3102   PetscValidHeaderSpecific(*B,MAT_CLASSID,4);
3103   PetscValidPointer(flag,5);
3104   PetscValidHeaderSpecific(ts,TS_CLASSID,6);
3105   ierr = (ts->ops->snesjacobian)(snes,U,A,B,flag,ts);CHKERRQ(ierr);
3106   PetscFunctionReturn(0);
3107 }
3108 
3109 #undef __FUNCT__
3110 #define __FUNCT__ "TSComputeRHSFunctionLinear"
3111 /*@C
3112    TSComputeRHSFunctionLinear - Evaluate the right hand side via the user-provided Jacobian, for linear problems only
3113 
3114    Collective on TS
3115 
3116    Input Arguments:
3117 +  ts - time stepping context
3118 .  t - time at which to evaluate
3119 .  U - state at which to evaluate
3120 -  ctx - context
3121 
3122    Output Arguments:
3123 .  F - right hand side
3124 
3125    Level: intermediate
3126 
3127    Notes:
3128    This function is intended to be passed to TSSetRHSFunction() to evaluate the right hand side for linear problems.
3129    The matrix (and optionally the evaluation context) should be passed to TSSetRHSJacobian().
3130 
3131 .seealso: TSSetRHSFunction(), TSSetRHSJacobian(), TSComputeRHSJacobianConstant()
3132 @*/
3133 PetscErrorCode TSComputeRHSFunctionLinear(TS ts,PetscReal t,Vec U,Vec F,void *ctx)
3134 {
3135   PetscErrorCode ierr;
3136   Mat            Arhs,Brhs;
3137   MatStructure   flg2;
3138 
3139   PetscFunctionBegin;
3140   ierr = TSGetRHSMats_Private(ts,&Arhs,&Brhs);CHKERRQ(ierr);
3141   ierr = TSComputeRHSJacobian(ts,t,U,&Arhs,&Brhs,&flg2);CHKERRQ(ierr);
3142   ierr = MatMult(Arhs,U,F);CHKERRQ(ierr);
3143   PetscFunctionReturn(0);
3144 }
3145 
3146 #undef __FUNCT__
3147 #define __FUNCT__ "TSComputeRHSJacobianConstant"
3148 /*@C
3149    TSComputeRHSJacobianConstant - Reuses a Jacobian that is time-independent.
3150 
3151    Collective on TS
3152 
3153    Input Arguments:
3154 +  ts - time stepping context
3155 .  t - time at which to evaluate
3156 .  U - state at which to evaluate
3157 -  ctx - context
3158 
3159    Output Arguments:
3160 +  A - pointer to operator
3161 .  B - pointer to preconditioning matrix
3162 -  flg - matrix structure flag
3163 
3164    Level: intermediate
3165 
3166    Notes:
3167    This function is intended to be passed to TSSetRHSJacobian() to evaluate the Jacobian for linear time-independent problems.
3168 
3169 .seealso: TSSetRHSFunction(), TSSetRHSJacobian(), TSComputeRHSFunctionLinear()
3170 @*/
3171 PetscErrorCode TSComputeRHSJacobianConstant(TS ts,PetscReal t,Vec U,Mat *A,Mat *B,MatStructure *flg,void *ctx)
3172 {
3173   PetscFunctionBegin;
3174   *flg = SAME_PRECONDITIONER;
3175   PetscFunctionReturn(0);
3176 }
3177 
3178 #undef __FUNCT__
3179 #define __FUNCT__ "TSComputeIFunctionLinear"
3180 /*@C
3181    TSComputeIFunctionLinear - Evaluate the left hand side via the user-provided Jacobian, for linear problems only
3182 
3183    Collective on TS
3184 
3185    Input Arguments:
3186 +  ts - time stepping context
3187 .  t - time at which to evaluate
3188 .  U - state at which to evaluate
3189 .  Udot - time derivative of state vector
3190 -  ctx - context
3191 
3192    Output Arguments:
3193 .  F - left hand side
3194 
3195    Level: intermediate
3196 
3197    Notes:
3198    The assumption here is that the left hand side is of the form A*Udot (and not A*Udot + B*U). For other cases, the
3199    user is required to write their own TSComputeIFunction.
3200    This function is intended to be passed to TSSetIFunction() to evaluate the left hand side for linear problems.
3201    The matrix (and optionally the evaluation context) should be passed to TSSetIJacobian().
3202 
3203 .seealso: TSSetIFunction(), TSSetIJacobian(), TSComputeIJacobianConstant()
3204 @*/
3205 PetscErrorCode TSComputeIFunctionLinear(TS ts,PetscReal t,Vec U,Vec Udot,Vec F,void *ctx)
3206 {
3207   PetscErrorCode ierr;
3208   Mat            A,B;
3209   MatStructure   flg2;
3210 
3211   PetscFunctionBegin;
3212   ierr = TSGetIJacobian(ts,&A,&B,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);
3213   ierr = TSComputeIJacobian(ts,t,U,Udot,1.0,&A,&B,&flg2,PETSC_TRUE);CHKERRQ(ierr);
3214   ierr = MatMult(A,Udot,F);CHKERRQ(ierr);
3215   PetscFunctionReturn(0);
3216 }
3217 
3218 #undef __FUNCT__
3219 #define __FUNCT__ "TSComputeIJacobianConstant"
3220 /*@C
3221    TSComputeIJacobianConstant - Reuses a Jacobian that is time-independent.
3222 
3223    Collective on TS
3224 
3225    Input Arguments:
3226 +  ts - time stepping context
3227 .  t - time at which to evaluate
3228 .  U - state at which to evaluate
3229 .  Udot - time derivative of state vector
3230 .  shift - shift to apply
3231 -  ctx - context
3232 
3233    Output Arguments:
3234 +  A - pointer to operator
3235 .  B - pointer to preconditioning matrix
3236 -  flg - matrix structure flag
3237 
3238    Level: intermediate
3239 
3240    Notes:
3241    This function is intended to be passed to TSSetIJacobian() to evaluate the Jacobian for linear time-independent problems.
3242 
3243 .seealso: TSSetIFunction(), TSSetIJacobian(), TSComputeIFunctionLinear()
3244 @*/
3245 PetscErrorCode TSComputeIJacobianConstant(TS ts,PetscReal t,Vec U,Vec Udot,PetscReal shift,Mat *A,Mat *B,MatStructure *flg,void *ctx)
3246 {
3247   PetscFunctionBegin;
3248   *flg = SAME_PRECONDITIONER;
3249   PetscFunctionReturn(0);
3250 }
3251 
3252 #undef __FUNCT__
3253 #define __FUNCT__ "TSGetConvergedReason"
3254 /*@
3255    TSGetConvergedReason - Gets the reason the TS iteration was stopped.
3256 
3257    Not Collective
3258 
3259    Input Parameter:
3260 .  ts - the TS context
3261 
3262    Output Parameter:
3263 .  reason - negative value indicates diverged, positive value converged, see TSConvergedReason or the
3264             manual pages for the individual convergence tests for complete lists
3265 
3266    Level: beginner
3267 
3268    Notes:
3269    Can only be called after the call to TSSolve() is complete.
3270 
3271 .keywords: TS, nonlinear, set, convergence, test
3272 
3273 .seealso: TSSetConvergenceTest(), TSConvergedReason
3274 @*/
3275 PetscErrorCode  TSGetConvergedReason(TS ts,TSConvergedReason *reason)
3276 {
3277   PetscFunctionBegin;
3278   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
3279   PetscValidPointer(reason,2);
3280   *reason = ts->reason;
3281   PetscFunctionReturn(0);
3282 }
3283 
3284 #undef __FUNCT__
3285 #define __FUNCT__ "TSSetConvergedReason"
3286 /*@
3287    TSSetConvergedReason - Sets the reason for handling the convergence of TSSolve.
3288 
3289    Not Collective
3290 
3291    Input Parameter:
3292 +  ts - the TS context
3293 .  reason - negative value indicates diverged, positive value converged, see TSConvergedReason or the
3294             manual pages for the individual convergence tests for complete lists
3295 
3296    Level: advanced
3297 
3298    Notes:
3299    Can only be called during TSSolve() is active.
3300 
3301 .keywords: TS, nonlinear, set, convergence, test
3302 
3303 .seealso: TSConvergedReason
3304 @*/
3305 PetscErrorCode  TSSetConvergedReason(TS ts,TSConvergedReason reason)
3306 {
3307   PetscFunctionBegin;
3308   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
3309   ts->reason = reason;
3310   PetscFunctionReturn(0);
3311 }
3312 
3313 #undef __FUNCT__
3314 #define __FUNCT__ "TSGetSolveTime"
3315 /*@
3316    TSGetSolveTime - Gets the time after a call to TSSolve()
3317 
3318    Not Collective
3319 
3320    Input Parameter:
3321 .  ts - the TS context
3322 
3323    Output Parameter:
3324 .  ftime - the final time. This time should correspond to the final time set with TSSetDuration()
3325 
3326    Level: beginner
3327 
3328    Notes:
3329    Can only be called after the call to TSSolve() is complete.
3330 
3331 .keywords: TS, nonlinear, set, convergence, test
3332 
3333 .seealso: TSSetConvergenceTest(), TSConvergedReason
3334 @*/
3335 PetscErrorCode  TSGetSolveTime(TS ts,PetscReal *ftime)
3336 {
3337   PetscFunctionBegin;
3338   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
3339   PetscValidPointer(ftime,2);
3340   *ftime = ts->solvetime;
3341   PetscFunctionReturn(0);
3342 }
3343 
3344 #undef __FUNCT__
3345 #define __FUNCT__ "TSGetSNESIterations"
3346 /*@
3347    TSGetSNESIterations - Gets the total number of nonlinear iterations
3348    used by the time integrator.
3349 
3350    Not Collective
3351 
3352    Input Parameter:
3353 .  ts - TS context
3354 
3355    Output Parameter:
3356 .  nits - number of nonlinear iterations
3357 
3358    Notes:
3359    This counter is reset to zero for each successive call to TSSolve().
3360 
3361    Level: intermediate
3362 
3363 .keywords: TS, get, number, nonlinear, iterations
3364 
3365 .seealso:  TSGetKSPIterations()
3366 @*/
3367 PetscErrorCode TSGetSNESIterations(TS ts,PetscInt *nits)
3368 {
3369   PetscFunctionBegin;
3370   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
3371   PetscValidIntPointer(nits,2);
3372   *nits = ts->snes_its;
3373   PetscFunctionReturn(0);
3374 }
3375 
3376 #undef __FUNCT__
3377 #define __FUNCT__ "TSGetKSPIterations"
3378 /*@
3379    TSGetKSPIterations - Gets the total number of linear iterations
3380    used by the time integrator.
3381 
3382    Not Collective
3383 
3384    Input Parameter:
3385 .  ts - TS context
3386 
3387    Output Parameter:
3388 .  lits - number of linear iterations
3389 
3390    Notes:
3391    This counter is reset to zero for each successive call to TSSolve().
3392 
3393    Level: intermediate
3394 
3395 .keywords: TS, get, number, linear, iterations
3396 
3397 .seealso:  TSGetSNESIterations(), SNESGetKSPIterations()
3398 @*/
3399 PetscErrorCode TSGetKSPIterations(TS ts,PetscInt *lits)
3400 {
3401   PetscFunctionBegin;
3402   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
3403   PetscValidIntPointer(lits,2);
3404   *lits = ts->ksp_its;
3405   PetscFunctionReturn(0);
3406 }
3407 
3408 #undef __FUNCT__
3409 #define __FUNCT__ "TSGetStepRejections"
3410 /*@
3411    TSGetStepRejections - Gets the total number of rejected steps.
3412 
3413    Not Collective
3414 
3415    Input Parameter:
3416 .  ts - TS context
3417 
3418    Output Parameter:
3419 .  rejects - number of steps rejected
3420 
3421    Notes:
3422    This counter is reset to zero for each successive call to TSSolve().
3423 
3424    Level: intermediate
3425 
3426 .keywords: TS, get, number
3427 
3428 .seealso:  TSGetSNESIterations(), TSGetKSPIterations(), TSSetMaxStepRejections(), TSGetSNESFailures(), TSSetMaxSNESFailures(), TSSetErrorIfStepFails()
3429 @*/
3430 PetscErrorCode TSGetStepRejections(TS ts,PetscInt *rejects)
3431 {
3432   PetscFunctionBegin;
3433   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
3434   PetscValidIntPointer(rejects,2);
3435   *rejects = ts->reject;
3436   PetscFunctionReturn(0);
3437 }
3438 
3439 #undef __FUNCT__
3440 #define __FUNCT__ "TSGetSNESFailures"
3441 /*@
3442    TSGetSNESFailures - Gets the total number of failed SNES solves
3443 
3444    Not Collective
3445 
3446    Input Parameter:
3447 .  ts - TS context
3448 
3449    Output Parameter:
3450 .  fails - number of failed nonlinear solves
3451 
3452    Notes:
3453    This counter is reset to zero for each successive call to TSSolve().
3454 
3455    Level: intermediate
3456 
3457 .keywords: TS, get, number
3458 
3459 .seealso:  TSGetSNESIterations(), TSGetKSPIterations(), TSSetMaxStepRejections(), TSGetStepRejections(), TSSetMaxSNESFailures()
3460 @*/
3461 PetscErrorCode TSGetSNESFailures(TS ts,PetscInt *fails)
3462 {
3463   PetscFunctionBegin;
3464   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
3465   PetscValidIntPointer(fails,2);
3466   *fails = ts->num_snes_failures;
3467   PetscFunctionReturn(0);
3468 }
3469 
3470 #undef __FUNCT__
3471 #define __FUNCT__ "TSSetMaxStepRejections"
3472 /*@
3473    TSSetMaxStepRejections - Sets the maximum number of step rejections before a step fails
3474 
3475    Not Collective
3476 
3477    Input Parameter:
3478 +  ts - TS context
3479 -  rejects - maximum number of rejected steps, pass -1 for unlimited
3480 
3481    Notes:
3482    The counter is reset to zero for each step
3483 
3484    Options Database Key:
3485  .  -ts_max_reject - Maximum number of step rejections before a step fails
3486 
3487    Level: intermediate
3488 
3489 .keywords: TS, set, maximum, number
3490 
3491 .seealso:  TSGetSNESIterations(), TSGetKSPIterations(), TSSetMaxSNESFailures(), TSGetStepRejections(), TSGetSNESFailures(), TSSetErrorIfStepFails(), TSGetConvergedReason()
3492 @*/
3493 PetscErrorCode TSSetMaxStepRejections(TS ts,PetscInt rejects)
3494 {
3495   PetscFunctionBegin;
3496   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
3497   ts->max_reject = rejects;
3498   PetscFunctionReturn(0);
3499 }
3500 
3501 #undef __FUNCT__
3502 #define __FUNCT__ "TSSetMaxSNESFailures"
3503 /*@
3504    TSSetMaxSNESFailures - Sets the maximum number of failed SNES solves
3505 
3506    Not Collective
3507 
3508    Input Parameter:
3509 +  ts - TS context
3510 -  fails - maximum number of failed nonlinear solves, pass -1 for unlimited
3511 
3512    Notes:
3513    The counter is reset to zero for each successive call to TSSolve().
3514 
3515    Options Database Key:
3516  .  -ts_max_snes_failures - Maximum number of nonlinear solve failures
3517 
3518    Level: intermediate
3519 
3520 .keywords: TS, set, maximum, number
3521 
3522 .seealso:  TSGetSNESIterations(), TSGetKSPIterations(), TSSetMaxStepRejections(), TSGetStepRejections(), TSGetSNESFailures(), SNESGetConvergedReason(), TSGetConvergedReason()
3523 @*/
3524 PetscErrorCode TSSetMaxSNESFailures(TS ts,PetscInt fails)
3525 {
3526   PetscFunctionBegin;
3527   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
3528   ts->max_snes_failures = fails;
3529   PetscFunctionReturn(0);
3530 }
3531 
3532 #undef __FUNCT__
3533 #define __FUNCT__ "TSSetErrorIfStepFails()"
3534 /*@
3535    TSSetErrorIfStepFails - Error if no step succeeds
3536 
3537    Not Collective
3538 
3539    Input Parameter:
3540 +  ts - TS context
3541 -  err - PETSC_TRUE to error if no step succeeds, PETSC_FALSE to return without failure
3542 
3543    Options Database Key:
3544  .  -ts_error_if_step_fails - Error if no step succeeds
3545 
3546    Level: intermediate
3547 
3548 .keywords: TS, set, error
3549 
3550 .seealso:  TSGetSNESIterations(), TSGetKSPIterations(), TSSetMaxStepRejections(), TSGetStepRejections(), TSGetSNESFailures(), TSSetErrorIfStepFails(), TSGetConvergedReason()
3551 @*/
3552 PetscErrorCode TSSetErrorIfStepFails(TS ts,PetscBool err)
3553 {
3554   PetscFunctionBegin;
3555   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
3556   ts->errorifstepfailed = err;
3557   PetscFunctionReturn(0);
3558 }
3559 
3560 #undef __FUNCT__
3561 #define __FUNCT__ "TSMonitorSolutionBinary"
3562 /*@C
3563    TSMonitorSolutionBinary - Monitors progress of the TS solvers by VecView() for the solution at each timestep. Normally the viewer is a binary file
3564 
3565    Collective on TS
3566 
3567    Input Parameters:
3568 +  ts - the TS context
3569 .  step - current time-step
3570 .  ptime - current time
3571 .  u - current state
3572 -  viewer - binary viewer
3573 
3574    Level: intermediate
3575 
3576 .keywords: TS,  vector, monitor, view
3577 
3578 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView()
3579 @*/
3580 PetscErrorCode  TSMonitorSolutionBinary(TS ts,PetscInt step,PetscReal ptime,Vec u,void *viewer)
3581 {
3582   PetscErrorCode ierr;
3583   PetscViewer    v = (PetscViewer)viewer;
3584 
3585   PetscFunctionBegin;
3586   ierr = VecView(u,v);CHKERRQ(ierr);
3587   PetscFunctionReturn(0);
3588 }
3589 
3590 #undef __FUNCT__
3591 #define __FUNCT__ "TSMonitorSolutionVTK"
3592 /*@C
3593    TSMonitorSolutionVTK - Monitors progress of the TS solvers by VecView() for the solution at each timestep.
3594 
3595    Collective on TS
3596 
3597    Input Parameters:
3598 +  ts - the TS context
3599 .  step - current time-step
3600 .  ptime - current time
3601 .  u - current state
3602 -  filenametemplate - string containing a format specifier for the integer time step (e.g. %03D)
3603 
3604    Level: intermediate
3605 
3606    Notes:
3607    The VTK format does not allow writing multiple time steps in the same file, therefore a different file will be written for each time step.
3608    These are named according to the file name template.
3609 
3610    This function is normally passed as an argument to TSMonitorSet() along with TSMonitorSolutionVTKDestroy().
3611 
3612 .keywords: TS,  vector, monitor, view
3613 
3614 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView()
3615 @*/
3616 PetscErrorCode TSMonitorSolutionVTK(TS ts,PetscInt step,PetscReal ptime,Vec u,void *filenametemplate)
3617 {
3618   PetscErrorCode ierr;
3619   char           filename[PETSC_MAX_PATH_LEN];
3620   PetscViewer    viewer;
3621 
3622   PetscFunctionBegin;
3623   ierr = PetscSNPrintf(filename,sizeof(filename),(const char*)filenametemplate,step);CHKERRQ(ierr);
3624   ierr = PetscViewerVTKOpen(((PetscObject)ts)->comm,filename,FILE_MODE_WRITE,&viewer);CHKERRQ(ierr);
3625   ierr = VecView(u,viewer);CHKERRQ(ierr);
3626   ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr);
3627   PetscFunctionReturn(0);
3628 }
3629 
3630 #undef __FUNCT__
3631 #define __FUNCT__ "TSMonitorSolutionVTKDestroy"
3632 /*@C
3633    TSMonitorSolutionVTKDestroy - Destroy context for monitoring
3634 
3635    Collective on TS
3636 
3637    Input Parameters:
3638 .  filenametemplate - string containing a format specifier for the integer time step (e.g. %03D)
3639 
3640    Level: intermediate
3641 
3642    Note:
3643    This function is normally passed to TSMonitorSet() along with TSMonitorSolutionVTK().
3644 
3645 .keywords: TS,  vector, monitor, view
3646 
3647 .seealso: TSMonitorSet(), TSMonitorSolutionVTK()
3648 @*/
3649 PetscErrorCode TSMonitorSolutionVTKDestroy(void *filenametemplate)
3650 {
3651   PetscErrorCode ierr;
3652 
3653   PetscFunctionBegin;
3654   ierr = PetscFree(*(char**)filenametemplate);CHKERRQ(ierr);
3655   PetscFunctionReturn(0);
3656 }
3657 
3658 #undef __FUNCT__
3659 #define __FUNCT__ "TSGetTSAdapt"
3660 /*@
3661    TSGetTSAdapt - Get the adaptive controller context for the current method
3662 
3663    Collective on TS if controller has not been created yet
3664 
3665    Input Arguments:
3666 .  ts - time stepping context
3667 
3668    Output Arguments:
3669 .  adapt - adaptive controller
3670 
3671    Level: intermediate
3672 
3673 .seealso: TSAdapt, TSAdaptSetType(), TSAdaptChoose()
3674 @*/
3675 PetscErrorCode TSGetTSAdapt(TS ts,TSAdapt *adapt)
3676 {
3677   PetscErrorCode ierr;
3678 
3679   PetscFunctionBegin;
3680   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
3681   PetscValidPointer(adapt,2);
3682   if (!ts->adapt) {
3683     ierr = TSAdaptCreate(((PetscObject)ts)->comm,&ts->adapt);CHKERRQ(ierr);
3684     ierr = PetscLogObjectParent(ts,ts->adapt);CHKERRQ(ierr);
3685     ierr = PetscObjectIncrementTabLevel((PetscObject)ts->adapt,(PetscObject)ts,1);CHKERRQ(ierr);
3686   }
3687   *adapt = ts->adapt;
3688   PetscFunctionReturn(0);
3689 }
3690 
3691 #undef __FUNCT__
3692 #define __FUNCT__ "TSSetTolerances"
3693 /*@
3694    TSSetTolerances - Set tolerances for local truncation error when using adaptive controller
3695 
3696    Logically Collective
3697 
3698    Input Arguments:
3699 +  ts - time integration context
3700 .  atol - scalar absolute tolerances, PETSC_DECIDE to leave current value
3701 .  vatol - vector of absolute tolerances or PETSC_NULL, used in preference to atol if present
3702 .  rtol - scalar relative tolerances, PETSC_DECIDE to leave current value
3703 -  vrtol - vector of relative tolerances or PETSC_NULL, used in preference to atol if present
3704 
3705    Level: beginner
3706 
3707 .seealso: TS, TSAdapt, TSVecNormWRMS(), TSGetTolerances()
3708 @*/
3709 PetscErrorCode TSSetTolerances(TS ts,PetscReal atol,Vec vatol,PetscReal rtol,Vec vrtol)
3710 {
3711   PetscErrorCode ierr;
3712 
3713   PetscFunctionBegin;
3714   if (atol != PETSC_DECIDE && atol != PETSC_DEFAULT) ts->atol = atol;
3715   if (vatol) {
3716     ierr = PetscObjectReference((PetscObject)vatol);CHKERRQ(ierr);
3717     ierr = VecDestroy(&ts->vatol);CHKERRQ(ierr);
3718     ts->vatol = vatol;
3719   }
3720   if (rtol != PETSC_DECIDE && rtol != PETSC_DEFAULT) ts->rtol = rtol;
3721   if (vrtol) {
3722     ierr = PetscObjectReference((PetscObject)vrtol);CHKERRQ(ierr);
3723     ierr = VecDestroy(&ts->vrtol);CHKERRQ(ierr);
3724     ts->vrtol = vrtol;
3725   }
3726   PetscFunctionReturn(0);
3727 }
3728 
3729 #undef __FUNCT__
3730 #define __FUNCT__ "TSGetTolerances"
3731 /*@
3732    TSGetTolerances - Get tolerances for local truncation error when using adaptive controller
3733 
3734    Logically Collective
3735 
3736    Input Arguments:
3737 .  ts - time integration context
3738 
3739    Output Arguments:
3740 +  atol - scalar absolute tolerances, PETSC_NULL to ignore
3741 .  vatol - vector of absolute tolerances, PETSC_NULL to ignore
3742 .  rtol - scalar relative tolerances, PETSC_NULL to ignore
3743 -  vrtol - vector of relative tolerances, PETSC_NULL to ignore
3744 
3745    Level: beginner
3746 
3747 .seealso: TS, TSAdapt, TSVecNormWRMS(), TSSetTolerances()
3748 @*/
3749 PetscErrorCode TSGetTolerances(TS ts,PetscReal *atol,Vec *vatol,PetscReal *rtol,Vec *vrtol)
3750 {
3751   PetscFunctionBegin;
3752   if (atol)  *atol  = ts->atol;
3753   if (vatol) *vatol = ts->vatol;
3754   if (rtol)  *rtol  = ts->rtol;
3755   if (vrtol) *vrtol = ts->vrtol;
3756   PetscFunctionReturn(0);
3757 }
3758 
3759 #undef __FUNCT__
3760 #define __FUNCT__ "TSErrorNormWRMS"
3761 /*@
3762    TSErrorNormWRMS - compute a weighted norm of the difference between a vector and the current state
3763 
3764    Collective on TS
3765 
3766    Input Arguments:
3767 +  ts - time stepping context
3768 -  Y - state vector to be compared to ts->vec_sol
3769 
3770    Output Arguments:
3771 .  norm - weighted norm, a value of 1.0 is considered small
3772 
3773    Level: developer
3774 
3775 .seealso: TSSetTolerances()
3776 @*/
3777 PetscErrorCode TSErrorNormWRMS(TS ts,Vec Y,PetscReal *norm)
3778 {
3779   PetscErrorCode    ierr;
3780   PetscInt          i,n,N;
3781   const PetscScalar *u,*y;
3782   Vec               U;
3783   PetscReal         sum,gsum;
3784 
3785   PetscFunctionBegin;
3786   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
3787   PetscValidHeaderSpecific(Y,VEC_CLASSID,2);
3788   PetscValidPointer(norm,3);
3789   U = ts->vec_sol;
3790   PetscCheckSameTypeAndComm(U,1,Y,2);
3791   if (U == Y) SETERRQ(((PetscObject)U)->comm,PETSC_ERR_ARG_IDN,"Y cannot be the TS solution vector");
3792 
3793   ierr = VecGetSize(U,&N);CHKERRQ(ierr);
3794   ierr = VecGetLocalSize(U,&n);CHKERRQ(ierr);
3795   ierr = VecGetArrayRead(U,&u);CHKERRQ(ierr);
3796   ierr = VecGetArrayRead(Y,&y);CHKERRQ(ierr);
3797   sum = 0.;
3798   if (ts->vatol && ts->vrtol) {
3799     const PetscScalar *atol,*rtol;
3800     ierr = VecGetArrayRead(ts->vatol,&atol);CHKERRQ(ierr);
3801     ierr = VecGetArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr);
3802     for (i=0; i<n; i++) {
3803       PetscReal tol = PetscRealPart(atol[i]) + PetscRealPart(rtol[i]) * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i]));
3804       sum += PetscSqr(PetscAbsScalar(y[i] - u[i]) / tol);
3805     }
3806     ierr = VecRestoreArrayRead(ts->vatol,&atol);CHKERRQ(ierr);
3807     ierr = VecRestoreArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr);
3808   } else if (ts->vatol) {       /* vector atol, scalar rtol */
3809     const PetscScalar *atol;
3810     ierr = VecGetArrayRead(ts->vatol,&atol);CHKERRQ(ierr);
3811     for (i=0; i<n; i++) {
3812       PetscReal tol = PetscRealPart(atol[i]) + ts->rtol * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i]));
3813       sum += PetscSqr(PetscAbsScalar(y[i] - u[i]) / tol);
3814     }
3815     ierr = VecRestoreArrayRead(ts->vatol,&atol);CHKERRQ(ierr);
3816   } else if (ts->vrtol) {       /* scalar atol, vector rtol */
3817     const PetscScalar *rtol;
3818     ierr = VecGetArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr);
3819     for (i=0; i<n; i++) {
3820       PetscReal tol = ts->atol + PetscRealPart(rtol[i]) * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i]));
3821       sum += PetscSqr(PetscAbsScalar(y[i] - u[i]) / tol);
3822     }
3823     ierr = VecRestoreArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr);
3824   } else {                      /* scalar atol, scalar rtol */
3825     for (i=0; i<n; i++) {
3826       PetscReal tol = ts->atol + ts->rtol * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i]));
3827       sum += PetscSqr(PetscAbsScalar(y[i] - u[i]) / tol);
3828     }
3829   }
3830   ierr = VecRestoreArrayRead(U,&u);CHKERRQ(ierr);
3831   ierr = VecRestoreArrayRead(Y,&y);CHKERRQ(ierr);
3832 
3833   ierr = MPI_Allreduce(&sum,&gsum,1,MPIU_REAL,MPIU_SUM,((PetscObject)ts)->comm);CHKERRQ(ierr);
3834   *norm = PetscSqrtReal(gsum / N);
3835   if (PetscIsInfOrNanScalar(*norm)) SETERRQ(((PetscObject)ts)->comm,PETSC_ERR_FP,"Infinite or not-a-number generated in norm");
3836   PetscFunctionReturn(0);
3837 }
3838 
3839 #undef __FUNCT__
3840 #define __FUNCT__ "TSSetCFLTimeLocal"
3841 /*@
3842    TSSetCFLTimeLocal - Set the local CFL constraint relative to forward Euler
3843 
3844    Logically Collective on TS
3845 
3846    Input Arguments:
3847 +  ts - time stepping context
3848 -  cfltime - maximum stable time step if using forward Euler (value can be different on each process)
3849 
3850    Note:
3851    After calling this function, the global CFL time can be obtained by calling TSGetCFLTime()
3852 
3853    Level: intermediate
3854 
3855 .seealso: TSGetCFLTime(), TSADAPTCFL
3856 @*/
3857 PetscErrorCode TSSetCFLTimeLocal(TS ts,PetscReal cfltime)
3858 {
3859   PetscFunctionBegin;
3860   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
3861   ts->cfltime_local = cfltime;
3862   ts->cfltime = -1.;
3863   PetscFunctionReturn(0);
3864 }
3865 
3866 #undef __FUNCT__
3867 #define __FUNCT__ "TSGetCFLTime"
3868 /*@
3869    TSGetCFLTime - Get the maximum stable time step according to CFL criteria applied to forward Euler
3870 
3871    Collective on TS
3872 
3873    Input Arguments:
3874 .  ts - time stepping context
3875 
3876    Output Arguments:
3877 .  cfltime - maximum stable time step for forward Euler
3878 
3879    Level: advanced
3880 
3881 .seealso: TSSetCFLTimeLocal()
3882 @*/
3883 PetscErrorCode TSGetCFLTime(TS ts,PetscReal *cfltime)
3884 {
3885   PetscErrorCode ierr;
3886 
3887   PetscFunctionBegin;
3888   if (ts->cfltime < 0) {
3889     ierr = MPI_Allreduce(&ts->cfltime_local,&ts->cfltime,1,MPIU_REAL,MPIU_MIN,((PetscObject)ts)->comm);CHKERRQ(ierr);
3890   }
3891   *cfltime = ts->cfltime;
3892   PetscFunctionReturn(0);
3893 }
3894 
3895 #undef __FUNCT__
3896 #define __FUNCT__ "TSVISetVariableBounds"
3897 /*@
3898    TSVISetVariableBounds - Sets the lower and upper bounds for the solution vector. xl <= x <= xu
3899 
3900    Input Parameters:
3901 .  ts   - the TS context.
3902 .  xl   - lower bound.
3903 .  xu   - upper bound.
3904 
3905    Notes:
3906    If this routine is not called then the lower and upper bounds are set to
3907    SNES_VI_NINF and SNES_VI_INF respectively during SNESSetUp().
3908 
3909    Level: advanced
3910 
3911 @*/
3912 PetscErrorCode TSVISetVariableBounds(TS ts, Vec xl, Vec xu)
3913 {
3914   PetscErrorCode ierr;
3915   SNES           snes;
3916 
3917   PetscFunctionBegin;
3918   ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr);
3919   ierr = SNESVISetVariableBounds(snes,xl,xu);CHKERRQ(ierr);
3920   PetscFunctionReturn(0);
3921 }
3922 
3923 #if defined(PETSC_HAVE_MATLAB_ENGINE)
3924 #include <mex.h>
3925 
3926 typedef struct {char *funcname; mxArray *ctx;} TSMatlabContext;
3927 
3928 #undef __FUNCT__
3929 #define __FUNCT__ "TSComputeFunction_Matlab"
3930 /*
3931    TSComputeFunction_Matlab - Calls the function that has been set with
3932                          TSSetFunctionMatlab().
3933 
3934    Collective on TS
3935 
3936    Input Parameters:
3937 +  snes - the TS context
3938 -  u - input vector
3939 
3940    Output Parameter:
3941 .  y - function vector, as set by TSSetFunction()
3942 
3943    Notes:
3944    TSComputeFunction() is typically used within nonlinear solvers
3945    implementations, so most users would not generally call this routine
3946    themselves.
3947 
3948    Level: developer
3949 
3950 .keywords: TS, nonlinear, compute, function
3951 
3952 .seealso: TSSetFunction(), TSGetFunction()
3953 */
3954 PetscErrorCode  TSComputeFunction_Matlab(TS snes,PetscReal time,Vec u,Vec udot,Vec y, void *ctx)
3955 {
3956   PetscErrorCode   ierr;
3957   TSMatlabContext *sctx = (TSMatlabContext *)ctx;
3958   int              nlhs = 1,nrhs = 7;
3959   mxArray          *plhs[1],*prhs[7];
3960   long long int    lx = 0,lxdot = 0,ly = 0,ls = 0;
3961 
3962   PetscFunctionBegin;
3963   PetscValidHeaderSpecific(snes,TS_CLASSID,1);
3964   PetscValidHeaderSpecific(u,VEC_CLASSID,3);
3965   PetscValidHeaderSpecific(udot,VEC_CLASSID,4);
3966   PetscValidHeaderSpecific(y,VEC_CLASSID,5);
3967   PetscCheckSameComm(snes,1,u,3);
3968   PetscCheckSameComm(snes,1,y,5);
3969 
3970   ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr);
3971   ierr = PetscMemcpy(&lx,&u,sizeof(u));CHKERRQ(ierr);
3972   ierr = PetscMemcpy(&lxdot,&udot,sizeof(udot));CHKERRQ(ierr);
3973   ierr = PetscMemcpy(&ly,&y,sizeof(u));CHKERRQ(ierr);
3974   prhs[0] =  mxCreateDoubleScalar((double)ls);
3975   prhs[1] =  mxCreateDoubleScalar(time);
3976   prhs[2] =  mxCreateDoubleScalar((double)lx);
3977   prhs[3] =  mxCreateDoubleScalar((double)lxdot);
3978   prhs[4] =  mxCreateDoubleScalar((double)ly);
3979   prhs[5] =  mxCreateString(sctx->funcname);
3980   prhs[6] =  sctx->ctx;
3981   ierr    =  mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscTSComputeFunctionInternal");CHKERRQ(ierr);
3982   ierr    =  mxGetScalar(plhs[0]);CHKERRQ(ierr);
3983   mxDestroyArray(prhs[0]);
3984   mxDestroyArray(prhs[1]);
3985   mxDestroyArray(prhs[2]);
3986   mxDestroyArray(prhs[3]);
3987   mxDestroyArray(prhs[4]);
3988   mxDestroyArray(prhs[5]);
3989   mxDestroyArray(plhs[0]);
3990   PetscFunctionReturn(0);
3991 }
3992 
3993 
3994 #undef __FUNCT__
3995 #define __FUNCT__ "TSSetFunctionMatlab"
3996 /*
3997    TSSetFunctionMatlab - Sets the function evaluation routine and function
3998    vector for use by the TS routines in solving ODEs
3999    equations from MATLAB. Here the function is a string containing the name of a MATLAB function
4000 
4001    Logically Collective on TS
4002 
4003    Input Parameters:
4004 +  ts - the TS context
4005 -  func - function evaluation routine
4006 
4007    Calling sequence of func:
4008 $    func (TS ts,PetscReal time,Vec u,Vec udot,Vec f,void *ctx);
4009 
4010    Level: beginner
4011 
4012 .keywords: TS, nonlinear, set, function
4013 
4014 .seealso: TSGetFunction(), TSComputeFunction(), TSSetJacobian(), TSSetFunction()
4015 */
4016 PetscErrorCode  TSSetFunctionMatlab(TS ts,const char *func,mxArray *ctx)
4017 {
4018   PetscErrorCode  ierr;
4019   TSMatlabContext *sctx;
4020 
4021   PetscFunctionBegin;
4022   /* currently sctx is memory bleed */
4023   ierr = PetscMalloc(sizeof(TSMatlabContext),&sctx);CHKERRQ(ierr);
4024   ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr);
4025   /*
4026      This should work, but it doesn't
4027   sctx->ctx = ctx;
4028   mexMakeArrayPersistent(sctx->ctx);
4029   */
4030   sctx->ctx = mxDuplicateArray(ctx);
4031   ierr = TSSetIFunction(ts,PETSC_NULL,TSComputeFunction_Matlab,sctx);CHKERRQ(ierr);
4032   PetscFunctionReturn(0);
4033 }
4034 
4035 #undef __FUNCT__
4036 #define __FUNCT__ "TSComputeJacobian_Matlab"
4037 /*
4038    TSComputeJacobian_Matlab - Calls the function that has been set with
4039                          TSSetJacobianMatlab().
4040 
4041    Collective on TS
4042 
4043    Input Parameters:
4044 +  ts - the TS context
4045 .  u - input vector
4046 .  A, B - the matrices
4047 -  ctx - user context
4048 
4049    Output Parameter:
4050 .  flag - structure of the matrix
4051 
4052    Level: developer
4053 
4054 .keywords: TS, nonlinear, compute, function
4055 
4056 .seealso: TSSetFunction(), TSGetFunction()
4057 @*/
4058 PetscErrorCode  TSComputeJacobian_Matlab(TS ts,PetscReal time,Vec u,Vec udot,PetscReal shift,Mat *A,Mat *B,MatStructure *flag, void *ctx)
4059 {
4060   PetscErrorCode  ierr;
4061   TSMatlabContext *sctx = (TSMatlabContext *)ctx;
4062   int             nlhs = 2,nrhs = 9;
4063   mxArray         *plhs[2],*prhs[9];
4064   long long int   lx = 0,lxdot = 0,lA = 0,ls = 0, lB = 0;
4065 
4066   PetscFunctionBegin;
4067   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
4068   PetscValidHeaderSpecific(u,VEC_CLASSID,3);
4069 
4070   /* call Matlab function in ctx with arguments u and y */
4071 
4072   ierr = PetscMemcpy(&ls,&ts,sizeof(ts));CHKERRQ(ierr);
4073   ierr = PetscMemcpy(&lx,&u,sizeof(u));CHKERRQ(ierr);
4074   ierr = PetscMemcpy(&lxdot,&udot,sizeof(u));CHKERRQ(ierr);
4075   ierr = PetscMemcpy(&lA,A,sizeof(u));CHKERRQ(ierr);
4076   ierr = PetscMemcpy(&lB,B,sizeof(u));CHKERRQ(ierr);
4077   prhs[0] =  mxCreateDoubleScalar((double)ls);
4078   prhs[1] =  mxCreateDoubleScalar((double)time);
4079   prhs[2] =  mxCreateDoubleScalar((double)lx);
4080   prhs[3] =  mxCreateDoubleScalar((double)lxdot);
4081   prhs[4] =  mxCreateDoubleScalar((double)shift);
4082   prhs[5] =  mxCreateDoubleScalar((double)lA);
4083   prhs[6] =  mxCreateDoubleScalar((double)lB);
4084   prhs[7] =  mxCreateString(sctx->funcname);
4085   prhs[8] =  sctx->ctx;
4086   ierr    =  mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscTSComputeJacobianInternal");CHKERRQ(ierr);
4087   ierr    =  mxGetScalar(plhs[0]);CHKERRQ(ierr);
4088   *flag   =  (MatStructure) mxGetScalar(plhs[1]);CHKERRQ(ierr);
4089   mxDestroyArray(prhs[0]);
4090   mxDestroyArray(prhs[1]);
4091   mxDestroyArray(prhs[2]);
4092   mxDestroyArray(prhs[3]);
4093   mxDestroyArray(prhs[4]);
4094   mxDestroyArray(prhs[5]);
4095   mxDestroyArray(prhs[6]);
4096   mxDestroyArray(prhs[7]);
4097   mxDestroyArray(plhs[0]);
4098   mxDestroyArray(plhs[1]);
4099   PetscFunctionReturn(0);
4100 }
4101 
4102 
4103 #undef __FUNCT__
4104 #define __FUNCT__ "TSSetJacobianMatlab"
4105 /*
4106    TSSetJacobianMatlab - Sets the Jacobian function evaluation routine and two empty Jacobian matrices
4107    vector for use by the TS routines in solving ODEs from MATLAB. Here the function is a string containing the name of a MATLAB function
4108 
4109    Logically Collective on TS
4110 
4111    Input Parameters:
4112 +  ts - the TS context
4113 .  A,B - Jacobian matrices
4114 .  func - function evaluation routine
4115 -  ctx - user context
4116 
4117    Calling sequence of func:
4118 $    flag = func (TS ts,PetscReal time,Vec u,Vec udot,Mat A,Mat B,void *ctx);
4119 
4120 
4121    Level: developer
4122 
4123 .keywords: TS, nonlinear, set, function
4124 
4125 .seealso: TSGetFunction(), TSComputeFunction(), TSSetJacobian(), TSSetFunction()
4126 */
4127 PetscErrorCode  TSSetJacobianMatlab(TS ts,Mat A,Mat B,const char *func,mxArray *ctx)
4128 {
4129   PetscErrorCode    ierr;
4130   TSMatlabContext *sctx;
4131 
4132   PetscFunctionBegin;
4133   /* currently sctx is memory bleed */
4134   ierr = PetscMalloc(sizeof(TSMatlabContext),&sctx);CHKERRQ(ierr);
4135   ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr);
4136   /*
4137      This should work, but it doesn't
4138   sctx->ctx = ctx;
4139   mexMakeArrayPersistent(sctx->ctx);
4140   */
4141   sctx->ctx = mxDuplicateArray(ctx);
4142   ierr = TSSetIJacobian(ts,A,B,TSComputeJacobian_Matlab,sctx);CHKERRQ(ierr);
4143   PetscFunctionReturn(0);
4144 }
4145 
4146 #undef __FUNCT__
4147 #define __FUNCT__ "TSMonitor_Matlab"
4148 /*
4149    TSMonitor_Matlab - Calls the function that has been set with TSMonitorSetMatlab().
4150 
4151    Collective on TS
4152 
4153 .seealso: TSSetFunction(), TSGetFunction()
4154 @*/
4155 PetscErrorCode  TSMonitor_Matlab(TS ts,PetscInt it, PetscReal time,Vec u, void *ctx)
4156 {
4157   PetscErrorCode  ierr;
4158   TSMatlabContext *sctx = (TSMatlabContext *)ctx;
4159   int             nlhs = 1,nrhs = 6;
4160   mxArray         *plhs[1],*prhs[6];
4161   long long int   lx = 0,ls = 0;
4162 
4163   PetscFunctionBegin;
4164   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
4165   PetscValidHeaderSpecific(u,VEC_CLASSID,4);
4166 
4167   ierr = PetscMemcpy(&ls,&ts,sizeof(ts));CHKERRQ(ierr);
4168   ierr = PetscMemcpy(&lx,&u,sizeof(u));CHKERRQ(ierr);
4169   prhs[0] =  mxCreateDoubleScalar((double)ls);
4170   prhs[1] =  mxCreateDoubleScalar((double)it);
4171   prhs[2] =  mxCreateDoubleScalar((double)time);
4172   prhs[3] =  mxCreateDoubleScalar((double)lx);
4173   prhs[4] =  mxCreateString(sctx->funcname);
4174   prhs[5] =  sctx->ctx;
4175   ierr    =  mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscTSMonitorInternal");CHKERRQ(ierr);
4176   ierr    =  mxGetScalar(plhs[0]);CHKERRQ(ierr);
4177   mxDestroyArray(prhs[0]);
4178   mxDestroyArray(prhs[1]);
4179   mxDestroyArray(prhs[2]);
4180   mxDestroyArray(prhs[3]);
4181   mxDestroyArray(prhs[4]);
4182   mxDestroyArray(plhs[0]);
4183   PetscFunctionReturn(0);
4184 }
4185 
4186 
4187 #undef __FUNCT__
4188 #define __FUNCT__ "TSMonitorSetMatlab"
4189 /*
4190    TSMonitorSetMatlab - Sets the monitor function from Matlab
4191 
4192    Level: developer
4193 
4194 .keywords: TS, nonlinear, set, function
4195 
4196 .seealso: TSGetFunction(), TSComputeFunction(), TSSetJacobian(), TSSetFunction()
4197 */
4198 PetscErrorCode  TSMonitorSetMatlab(TS ts,const char *func,mxArray *ctx)
4199 {
4200   PetscErrorCode    ierr;
4201   TSMatlabContext *sctx;
4202 
4203   PetscFunctionBegin;
4204   /* currently sctx is memory bleed */
4205   ierr = PetscMalloc(sizeof(TSMatlabContext),&sctx);CHKERRQ(ierr);
4206   ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr);
4207   /*
4208      This should work, but it doesn't
4209   sctx->ctx = ctx;
4210   mexMakeArrayPersistent(sctx->ctx);
4211   */
4212   sctx->ctx = mxDuplicateArray(ctx);
4213   ierr = TSMonitorSet(ts,TSMonitor_Matlab,sctx,PETSC_NULL);CHKERRQ(ierr);
4214   PetscFunctionReturn(0);
4215 }
4216 #endif
4217 
4218 
4219 
4220 #undef __FUNCT__
4221 #define __FUNCT__ "TSMonitorLGSolution"
4222 /*@C
4223    TSMonitorLGSolution - Monitors progress of the TS solvers by plotting each component of the solution vector
4224        in a time based line graph
4225 
4226    Collective on TS
4227 
4228    Input Parameters:
4229 +  ts - the TS context
4230 .  step - current time-step
4231 .  ptime - current time
4232 -  lg - a line graph object
4233 
4234    Level: intermediate
4235 
4236     Notes: each process in a parallel run displays its component solutions in a separate window
4237 
4238 .keywords: TS,  vector, monitor, view
4239 
4240 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView()
4241 @*/
4242 PetscErrorCode  TSMonitorLGSolution(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dummy)
4243 {
4244   PetscErrorCode    ierr;
4245   TSMonitorLGCtx    ctx = (TSMonitorLGCtx)dummy;
4246   const PetscScalar *yy;
4247   PetscInt          dim;
4248 
4249   PetscFunctionBegin;
4250   if (!step) {
4251     PetscDrawAxis  axis;
4252     ierr = PetscDrawLGGetAxis(ctx->lg,&axis);CHKERRQ(ierr);
4253     ierr = PetscDrawAxisSetLabels(axis,"Solution as function of time","Time","Solution");CHKERRQ(ierr);
4254     ierr = VecGetLocalSize(u,&dim);CHKERRQ(ierr);
4255     ierr = PetscDrawLGSetDimension(ctx->lg,dim);CHKERRQ(ierr);
4256     ierr = PetscDrawLGReset(ctx->lg);CHKERRQ(ierr);
4257   }
4258   ierr = VecGetArrayRead(u,&yy);CHKERRQ(ierr);
4259 #if defined(PETSC_USE_COMPLEX)
4260   {
4261     PetscReal *yreal;
4262     PetscInt i,n;
4263     ierr = VecGetLocalSize(u,&n);CHKERRQ(ierr);
4264     ierr = PetscMalloc(n*sizeof(PetscReal),&yreal);CHKERRQ(ierr);
4265     for (i=0; i<n; i++) yreal[i] = PetscRealPart(yy[i]);
4266     ierr = PetscDrawLGAddCommonPoint(ctx->lg,ptime,yreal);CHKERRQ(ierr);
4267     ierr = PetscFree(yreal);CHKERRQ(ierr);
4268   }
4269 #else
4270   ierr = PetscDrawLGAddCommonPoint(ctx->lg,ptime,yy);CHKERRQ(ierr);
4271 #endif
4272   ierr = VecRestoreArrayRead(u,&yy);CHKERRQ(ierr);
4273   if (((ctx->howoften > 0) && (!(step % ctx->howoften)) && (step > -1)) || ((ctx->howoften == -1) && (step == -1))){
4274     ierr = PetscDrawLGDraw(ctx->lg);CHKERRQ(ierr);
4275   }
4276   PetscFunctionReturn(0);
4277 }
4278 
4279 #undef __FUNCT__
4280 #define __FUNCT__ "TSMonitorLGError"
4281 /*@C
4282    TSMonitorLGError - Monitors progress of the TS solvers by plotting each component of the solution vector
4283        in a time based line graph
4284 
4285    Collective on TS
4286 
4287    Input Parameters:
4288 +  ts - the TS context
4289 .  step - current time-step
4290 .  ptime - current time
4291 -  lg - a line graph object
4292 
4293    Level: intermediate
4294 
4295    Notes:
4296    Only for sequential solves.
4297 
4298    The user must provide the solution using TSSetSolutionFunction() to use this monitor.
4299 
4300    Options Database Keys:
4301 .  -ts_monitor_lg_error - create a graphical monitor of error history
4302 
4303 .keywords: TS,  vector, monitor, view
4304 
4305 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSSetSolutionFunction()
4306 @*/
4307 PetscErrorCode  TSMonitorLGError(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dummy)
4308 {
4309   PetscErrorCode    ierr;
4310   TSMonitorLGCtx    ctx = (TSMonitorLGCtx)dummy;
4311   const PetscScalar *yy;
4312   Vec               y;
4313   PetscInt          dim;
4314 
4315   PetscFunctionBegin;
4316   if (!step) {
4317     PetscDrawAxis  axis;
4318     ierr = PetscDrawLGGetAxis(ctx->lg,&axis);CHKERRQ(ierr);
4319     ierr = PetscDrawAxisSetLabels(axis,"Error in solution as function of time","Time","Solution");CHKERRQ(ierr);
4320     ierr = VecGetLocalSize(u,&dim);CHKERRQ(ierr);
4321     ierr = PetscDrawLGSetDimension(ctx->lg,dim);CHKERRQ(ierr);
4322     ierr = PetscDrawLGReset(ctx->lg);CHKERRQ(ierr);
4323   }
4324   ierr = VecDuplicate(u,&y);CHKERRQ(ierr);
4325   ierr = TSComputeSolutionFunction(ts,ptime,y);CHKERRQ(ierr);
4326   ierr = VecAXPY(y,-1.0,u);CHKERRQ(ierr);
4327   ierr = VecGetArrayRead(y,&yy);CHKERRQ(ierr);
4328 #if defined(PETSC_USE_COMPLEX)
4329   {
4330     PetscReal *yreal;
4331     PetscInt  i,n;
4332     ierr = VecGetLocalSize(y,&n);CHKERRQ(ierr);
4333     ierr = PetscMalloc(n*sizeof(PetscReal),&yreal);CHKERRQ(ierr);
4334     for (i=0; i<n; i++) yreal[i] = PetscRealPart(yy[i]);
4335     ierr = PetscDrawLGAddCommonPoint(ctx->lg,ptime,yreal);CHKERRQ(ierr);
4336     ierr = PetscFree(yreal);CHKERRQ(ierr);
4337   }
4338 #else
4339   ierr = PetscDrawLGAddCommonPoint(ctx->lg,ptime,yy);CHKERRQ(ierr);
4340 #endif
4341   ierr = VecRestoreArrayRead(y,&yy);CHKERRQ(ierr);
4342   ierr = VecDestroy(&y);CHKERRQ(ierr);
4343   if (((ctx->howoften > 0) && (!(step % ctx->howoften)) && (step > -1)) || ((ctx->howoften == -1) && (step == -1))){
4344     ierr = PetscDrawLGDraw(ctx->lg);CHKERRQ(ierr);
4345   }
4346   PetscFunctionReturn(0);
4347 }
4348 
4349 #undef __FUNCT__
4350 #define __FUNCT__ "TSMonitorLGSNESIterations"
4351 PetscErrorCode TSMonitorLGSNESIterations(TS ts,PetscInt n,PetscReal ptime,Vec v,void *monctx)
4352 {
4353   TSMonitorLGCtx ctx = (TSMonitorLGCtx) monctx;
4354   PetscReal      x = ptime,y;
4355   PetscErrorCode ierr;
4356   PetscInt       its;
4357 
4358   PetscFunctionBegin;
4359   if (!n) {
4360     PetscDrawAxis  axis;
4361     ierr = PetscDrawLGGetAxis(ctx->lg,&axis);CHKERRQ(ierr);
4362     ierr = PetscDrawAxisSetLabels(axis,"Nonlinear iterations as function of time","Time","SNES Iterations");CHKERRQ(ierr);
4363     ierr = PetscDrawLGReset(ctx->lg);CHKERRQ(ierr);
4364     ctx->snes_its  = 0;
4365   }
4366   ierr = TSGetSNESIterations(ts,&its);CHKERRQ(ierr);
4367   y    = its - ctx->snes_its;
4368   ierr = PetscDrawLGAddPoint(ctx->lg,&x,&y);CHKERRQ(ierr);
4369   if (((ctx->howoften > 0) && (!(n % ctx->howoften)) && (n > -1)) || ((ctx->howoften == -1) && (n == -1))){
4370     ierr = PetscDrawLGDraw(ctx->lg);CHKERRQ(ierr);
4371   }
4372   ctx->snes_its = its;
4373   PetscFunctionReturn(0);
4374 }
4375 
4376 #undef __FUNCT__
4377 #define __FUNCT__ "TSMonitorLGKSPIterations"
4378 PetscErrorCode TSMonitorLGKSPIterations(TS ts,PetscInt n,PetscReal ptime,Vec v,void *monctx)
4379 {
4380   TSMonitorLGCtx ctx = (TSMonitorLGCtx) monctx;
4381   PetscReal      x = ptime,y;
4382   PetscErrorCode ierr;
4383   PetscInt       its;
4384 
4385   PetscFunctionBegin;
4386   if (!n) {
4387     PetscDrawAxis  axis;
4388     ierr = PetscDrawLGGetAxis(ctx->lg,&axis);CHKERRQ(ierr);
4389     ierr = PetscDrawAxisSetLabels(axis,"Linear iterations as function of time","Time","KSP Iterations");CHKERRQ(ierr);
4390     ierr = PetscDrawLGReset(ctx->lg);CHKERRQ(ierr);
4391     ctx->ksp_its = 0;
4392   }
4393   ierr = TSGetKSPIterations(ts,&its);CHKERRQ(ierr);
4394   y    = its - ctx->ksp_its;
4395   ierr = PetscDrawLGAddPoint(ctx->lg,&x,&y);CHKERRQ(ierr);
4396   if (((ctx->howoften > 0) && (!(n % ctx->howoften)) && (n > -1)) || ((ctx->howoften == -1) && (n == -1))){
4397     ierr = PetscDrawLGDraw(ctx->lg);CHKERRQ(ierr);
4398   }
4399   ctx->ksp_its = its;
4400   PetscFunctionReturn(0);
4401 }
4402 
4403 #undef __FUNCT__
4404 #define __FUNCT__ "TSComputeLinearStability"
4405 /*@
4406    TSComputeLinearStability - computes the linear stability function at a point
4407 
4408    Collective on TS and Vec
4409 
4410    Input Parameters:
4411 +  ts - the TS context
4412 -  xr,xi - real and imaginary part of input arguments
4413 
4414    Output Parameters:
4415 .  yr,yi - real and imaginary part of function value
4416 
4417    Level: developer
4418 
4419 .keywords: TS, compute
4420 
4421 .seealso: TSSetRHSFunction(), TSComputeIFunction()
4422 @*/
4423 PetscErrorCode TSComputeLinearStability(TS ts,PetscReal xr,PetscReal xi,PetscReal *yr,PetscReal *yi)
4424 {
4425   PetscErrorCode ierr;
4426 
4427   PetscFunctionBegin;
4428   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
4429   if (!ts->ops->linearstability) SETERRQ(((PetscObject)ts)->comm,PETSC_ERR_SUP,"Linearized stability function not provided for this method");
4430   ierr = (*ts->ops->linearstability)(ts,xr,xi,yr,yi);CHKERRQ(ierr);
4431   PetscFunctionReturn(0);
4432 }
4433