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