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