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