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