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