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