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