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