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