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