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