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