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