xref: /petsc/src/ts/interface/ts.c (revision 076585595fd0d56e996329fd73e4a2c1ffff8fe8)
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__ "TSGetSensitivity"
1735 /*@
1736    TSGetSensitivity - 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  TSGetSensitivity(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 TSSetSensitivity() 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__ "TSSetSensitivity"
2249 /*@
2250    TSSetSensitivity - 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  TSSetSensitivity(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 TSSetSensitivityP()");
2270   ts->numberadjs = numberadjs;
2271 
2272   PetscFunctionReturn(0);
2273 }
2274 
2275 #undef __FUNCT__
2276 #define __FUNCT__ "TSSetSensitivityP"
2277 /*@
2278    TSSetSensitivityP - 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  TSSetSensitivityP(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 TSSetSensitivity()");
2298   ts->numberadjs = numberadjs;
2299 
2300   PetscFunctionReturn(0);
2301 }
2302 
2303 #undef __FUNCT__
2304 #define __FUNCT__ "TSSetRHSJacobianP"
2305 /*@C
2306   TSSetRHSJacobianP - 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  TSSetRHSJacobianP(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__ "TSRHSJacobianP"
2347 /*@
2348   TSRHSJacobianP - 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   Notes:
2356   TSJacobianP() is typically used for sensitivity implementation,
2357   so most users would not generally call this routine themselves.
2358 
2359   Level: developer
2360 
2361 .keywords: TS, sensitivity
2362 .seealso: TSSetRHSJacobianP()
2363 @*/
2364 PetscErrorCode  TSRHSJacobianP(TS ts,PetscReal t,Vec X,Mat Amat)
2365 {
2366   PetscErrorCode ierr;
2367 
2368   PetscFunctionBegin;
2369   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
2370   PetscValidHeaderSpecific(X,VEC_CLASSID,3);
2371   PetscValidPointer(Amat,4);
2372 
2373   PetscStackPush("TS user JacobianP function for sensitivity analysis");
2374   ierr = (*ts->rhsjacobianp)(ts,t,X,Amat,ts->rhsjacobianpctx); CHKERRQ(ierr);
2375   PetscStackPop;
2376 
2377   PetscFunctionReturn(0);
2378 }
2379 
2380 #undef __FUNCT__
2381 #define __FUNCT__ "TSSetCostIntegrand"
2382 /*@C
2383     TSSetCostIntegrand - Sets the routine for evaluating the quadrature (or integral) term in a cost function,
2384     where Q_t = r(t,u).
2385 
2386     Logically Collective on TS
2387 
2388     Input Parameters:
2389 +   ts - the TS context obtained from TSCreate()
2390 .   q -  vector to put the computed quadrature term in the cost function (or NULL to have it created)
2391 .   fq - routine for evaluating the right-hand-side function
2392 -   ctx - [optional] user-defined context for private data for the
2393           function evaluation routine (may be NULL)
2394 
2395     Calling sequence of func:
2396 $     TSCostIntegrand(TS ts,PetscReal t,Vec u,PetscReal *f,void *ctx);
2397 
2398 +   t - current timestep
2399 .   u - input vector
2400 .   f - function vector
2401 -   ctx - [optional] user-defined function context
2402 
2403     Level: beginner
2404 
2405 .keywords: TS, sensitivity analysis, timestep, set, quadrature, function
2406 
2407 .seealso: TSSetRHSJacobianP(),TSSetSensitivity(),TSSetSensitivityP()
2408 @*/
2409 PetscErrorCode  TSSetCostIntegrand(TS ts,PetscInt numberadjs,Vec q,PetscErrorCode (*fq)(TS,PetscReal,Vec,Vec,void*),void *ctx)
2410 {
2411   PetscErrorCode ierr;
2412   PetscInt size;
2413 
2414   PetscFunctionBegin;
2415   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
2416   if (q) {
2417     PetscValidHeaderSpecific(q,VEC_CLASSID,2);
2418   } else {
2419     SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_USER,"TSSetCostIntegrand() requires a vector of size numberajds to hold the value of integrals as 3rd input parameter");
2420   }
2421   if (!ts->numberadjs) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_USER,"Call TSSetSensitivity() or TSSetSensitivityP() first so that the number of cost functions can be determined.");
2422   if (ts->numberadjs && ts->numberadjs!=numberadjs) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_USER,"The number of cost functions (2rd parameter of TSSetCostIntegrand()) is inconsistent with the one set by TSSetSensitivity() or TSSetSensitivityP()");
2423   ierr = VecGetSize(q,&size);CHKERRQ(ierr);
2424   ierr = VecZeroEntries(q);CHKERRQ(ierr);
2425   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 TSSetCostIntegrand()).");
2426 
2427   ierr = PetscObjectReference((PetscObject)q);CHKERRQ(ierr);
2428   ierr = VecDestroy(&ts->vec_costquad);CHKERRQ(ierr);
2429   ts->vec_costquad = q;
2430 
2431   ierr                  = VecDuplicate(ts->vec_costquad,&ts->vec_costintegrand);CHKERRQ(ierr);
2432   ts->costintegrand     = fq;
2433   ts->costintegrandctx  = ctx;
2434 
2435   PetscFunctionReturn(0);
2436 }
2437 
2438 #undef __FUNCT__
2439 #define __FUNCT__ "TSGetCostQuad"
2440 /*@
2441    TSGetCostQuad - Returns the values of the quadrature (or integral) terms in a cost function.
2442    It is valid to call the routine after a backward run.
2443 
2444    Not Collective
2445 
2446    Input Parameter:
2447 .  ts - the TS context obtained from TSCreate()
2448 
2449    Output Parameter:
2450 .  v - the vector containing the solution
2451 
2452    Level: intermediate
2453 
2454 .seealso: TSSetCostIntegrand()
2455 
2456 .keywords: TS, sensitivity analysis
2457 @*/
2458 PetscErrorCode  TSGetCostQuad(TS ts,Vec *v)
2459 {
2460   PetscFunctionBegin;
2461   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
2462   PetscValidPointer(v,2);
2463   *v = ts->vec_costquad;
2464   PetscFunctionReturn(0);
2465 }
2466 
2467 #undef __FUNCT__
2468 #define __FUNCT__ "TSComputeCostIntegrand"
2469 /*@
2470    TSComputeCostIntegrand - Evaluates the quadrature function in the cost functions.
2471 
2472    Input Parameters:
2473 +  ts - the TS context
2474 .  t - current time
2475 -  U - state vector
2476 
2477    Output Parameter:
2478 .  q - vector of size numberadjs to hold the outputs
2479 
2480    Note:
2481    Most users should not need to explicitly call this routine, as it
2482    is used internally within the sensitivity analysis context.
2483 
2484    Level: developer
2485 
2486 .keywords: TS, compute
2487 
2488 .seealso: TSSetCostIntegrand()
2489 @*/
2490 PetscErrorCode TSComputeCostIntegrand(TS ts,PetscReal t,Vec U,Vec q)
2491 {
2492   PetscErrorCode ierr;
2493 
2494   PetscFunctionBegin;
2495   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
2496   PetscValidHeaderSpecific(U,VEC_CLASSID,3);
2497   PetscValidHeaderSpecific(q,VEC_CLASSID,4);
2498 
2499   ierr = PetscLogEventBegin(TS_FunctionEval,ts,U,q,0);CHKERRQ(ierr);
2500   if (ts->costintegrand) {
2501     PetscStackPush("TS user integrand in the cost function");
2502     ierr = (*ts->costintegrand)(ts,t,U,q,ts->costintegrandctx);CHKERRQ(ierr);
2503     PetscStackPop;
2504   } else {
2505     ierr = VecZeroEntries(q);CHKERRQ(ierr);
2506   }
2507 
2508   ierr = PetscLogEventEnd(TS_FunctionEval,ts,U,q,0);CHKERRQ(ierr);
2509   PetscFunctionReturn(0);
2510 }
2511 
2512 #undef __FUNCT__
2513 #define __FUNCT__ "TSSetDRDYFunction"
2514 /*@C
2515   TSSetDRDYFunction - Sets the function that computes the gradient of the CostIntegrand function r w.r.t. states y.
2516 
2517   Logically Collective on TS
2518 
2519   Input Parameters:
2520 + ts   - The TS context obtained from TSCreate()
2521 - func - The function
2522 
2523   Calling sequence of func:
2524 . PetscErroCode func(TS ts,PetscReal t,Vec U,Vec *drdy,void *ctx);
2525 
2526   Level: intermediate
2527 
2528 .keywords: TS, sensitivity
2529 .seealso:
2530 @*/
2531 PetscErrorCode  TSSetDRDYFunction(TS ts,Vec *drdy,PetscErrorCode (*func)(TS,PetscReal,Vec,Vec*,void*),void *ctx)
2532 {
2533   PetscFunctionBegin;
2534   PetscValidHeaderSpecific(ts, TS_CLASSID,1);
2535 
2536   ts->drdyfunction    = func;
2537   ts->drdyfunctionctx = ctx;
2538   ts->vecs_drdy       = drdy;
2539   PetscFunctionReturn(0);
2540 }
2541 
2542 #undef __FUNCT__
2543 #define __FUNCT__ "TSComputeDRDYFunction"
2544 /*@
2545   TSComputeDRDYFunction - Runs the user-defined DRDY function.
2546 
2547   Collective on TS
2548 
2549   Input Parameters:
2550 . ts   - The TS context obtained from TSCreate()
2551 
2552   Notes:
2553   TSComputeDRDYFunction() is typically used for sensitivity implementation,
2554   so most users would not generally call this routine themselves.
2555 
2556   Level: developer
2557 
2558 .keywords: TS, sensitivity
2559 .seealso: TSComputeDRDYFunction()
2560 @*/
2561 PetscErrorCode  TSComputeDRDYFunction(TS ts,PetscReal t,Vec X,Vec *drdy)
2562 {
2563   PetscErrorCode ierr;
2564 
2565   PetscFunctionBegin;
2566   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
2567   PetscValidHeaderSpecific(X,VEC_CLASSID,3);
2568 
2569   PetscStackPush("TS user DRDY function for sensitivity analysis");
2570   ierr = (*ts->drdyfunction)(ts,t,X,drdy,ts->drdyfunctionctx); CHKERRQ(ierr);
2571   PetscStackPop;
2572   PetscFunctionReturn(0);
2573 }
2574 
2575 #undef __FUNCT__
2576 #define __FUNCT__ "TSSetDRDPFunction"
2577 /*@C
2578   TSSetDRDPFunction - Sets the function that computes the gradient of the CostIntegrand function w.r.t. parameters.
2579 
2580   Logically Collective on TS
2581 
2582   Input Parameters:
2583 + ts   - The TS context obtained from TSCreate()
2584 - func - The function
2585 
2586   Calling sequence of func:
2587 . func(TS ts,PetscReal t,Vec U,Vec *drdy,void *ctx);
2588 
2589   Level: intermediate
2590 
2591 .keywords: TS, sensitivity
2592 .seealso:
2593 @*/
2594 PetscErrorCode  TSSetDRDPFunction(TS ts,Vec *drdp,PetscErrorCode (*func)(TS,PetscReal,Vec,Vec*,void*),void *ctx)
2595 {
2596   PetscFunctionBegin;
2597   PetscValidHeaderSpecific(ts, TS_CLASSID,1);
2598 
2599   ts->drdpfunction    = func;
2600   ts->drdpfunctionctx = ctx;
2601   ts->vecs_drdp       = drdp;
2602 
2603   PetscFunctionReturn(0);
2604 }
2605 
2606 #undef __FUNCT__
2607 #define __FUNCT__ "TSComputeDRDPFunction"
2608 /*@
2609   TSComputeDRDPFunction - Runs the user-defined DRDP function.
2610 
2611   Collective on TS
2612 
2613   Input Parameters:
2614 . ts   - The TS context obtained from TSCreate()
2615 
2616   Notes:
2617   TSDRDPFunction() is typically used for sensitivity implementation,
2618   so most users would not generally call this routine themselves.
2619 
2620   Level: developer
2621 
2622 .keywords: TS, sensitivity
2623 .seealso: TSSetDRDPFunction()
2624 @*/
2625 PetscErrorCode  TSComputeDRDPFunction(TS ts,PetscReal t,Vec X,Vec *drdp)
2626 {
2627   PetscErrorCode ierr;
2628 
2629   PetscFunctionBegin;
2630   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
2631   PetscValidHeaderSpecific(X,VEC_CLASSID,3);
2632 
2633   PetscStackPush("TS user DRDP function for sensitivity analysis");
2634   ierr = (*ts->drdpfunction)(ts,t,X,drdp,ts->drdpfunctionctx); CHKERRQ(ierr);
2635   PetscStackPop;
2636 
2637   PetscFunctionReturn(0);
2638 }
2639 
2640 #undef __FUNCT__
2641 #define __FUNCT__ "TSSetPreStep"
2642 /*@C
2643   TSSetPreStep - Sets the general-purpose function
2644   called once at the beginning of each time step.
2645 
2646   Logically Collective on TS
2647 
2648   Input Parameters:
2649 + ts   - The TS context obtained from TSCreate()
2650 - func - The function
2651 
2652   Calling sequence of func:
2653 . func (TS ts);
2654 
2655   Level: intermediate
2656 
2657   Note:
2658   If a step is rejected, TSStep() will call this routine again before each attempt.
2659   The last completed time step number can be queried using TSGetTimeStepNumber(), the
2660   size of the step being attempted can be obtained using TSGetTimeStep().
2661 
2662 .keywords: TS, timestep
2663 .seealso: TSSetPreStage(), TSSetPostStage(), TSSetPostStep(), TSStep()
2664 @*/
2665 PetscErrorCode  TSSetPreStep(TS ts, PetscErrorCode (*func)(TS))
2666 {
2667   PetscFunctionBegin;
2668   PetscValidHeaderSpecific(ts, TS_CLASSID,1);
2669   ts->prestep = func;
2670   PetscFunctionReturn(0);
2671 }
2672 
2673 #undef __FUNCT__
2674 #define __FUNCT__ "TSPreStep"
2675 /*@
2676   TSPreStep - Runs the user-defined pre-step function.
2677 
2678   Collective on TS
2679 
2680   Input Parameters:
2681 . ts   - The TS context obtained from TSCreate()
2682 
2683   Notes:
2684   TSPreStep() is typically used within time stepping implementations,
2685   so most users would not generally call this routine themselves.
2686 
2687   Level: developer
2688 
2689 .keywords: TS, timestep
2690 .seealso: TSSetPreStep(), TSPreStage(), TSPostStage(), TSPostStep()
2691 @*/
2692 PetscErrorCode  TSPreStep(TS ts)
2693 {
2694   PetscErrorCode ierr;
2695 
2696   PetscFunctionBegin;
2697   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
2698   if (ts->prestep) {
2699     PetscStackCallStandard((*ts->prestep),(ts));
2700   }
2701   PetscFunctionReturn(0);
2702 }
2703 
2704 #undef __FUNCT__
2705 #define __FUNCT__ "TSSetPreStage"
2706 /*@C
2707   TSSetPreStage - Sets the general-purpose function
2708   called once at the beginning of each stage.
2709 
2710   Logically Collective on TS
2711 
2712   Input Parameters:
2713 + ts   - The TS context obtained from TSCreate()
2714 - func - The function
2715 
2716   Calling sequence of func:
2717 . PetscErrorCode func(TS ts, PetscReal stagetime);
2718 
2719   Level: intermediate
2720 
2721   Note:
2722   There may be several stages per time step. If the solve for a given stage fails, the step may be rejected and retried.
2723   The time step number being computed can be queried using TSGetTimeStepNumber() and the total size of the step being
2724   attempted can be obtained using TSGetTimeStep(). The time at the start of the step is available via TSGetTime().
2725 
2726 .keywords: TS, timestep
2727 .seealso: TSSetPostStage(), TSSetPreStep(), TSSetPostStep(), TSGetApplicationContext()
2728 @*/
2729 PetscErrorCode  TSSetPreStage(TS ts, PetscErrorCode (*func)(TS,PetscReal))
2730 {
2731   PetscFunctionBegin;
2732   PetscValidHeaderSpecific(ts, TS_CLASSID,1);
2733   ts->prestage = func;
2734   PetscFunctionReturn(0);
2735 }
2736 
2737 #undef __FUNCT__
2738 #define __FUNCT__ "TSSetPostStage"
2739 /*@C
2740   TSSetPostStage - Sets the general-purpose function
2741   called once at the end of each stage.
2742 
2743   Logically Collective on TS
2744 
2745   Input Parameters:
2746 + ts   - The TS context obtained from TSCreate()
2747 - func - The function
2748 
2749   Calling sequence of func:
2750 . PetscErrorCode func(TS ts, PetscReal stagetime, PetscInt stageindex, Vec* Y);
2751 
2752   Level: intermediate
2753 
2754   Note:
2755   There may be several stages per time step. If the solve for a given stage fails, the step may be rejected and retried.
2756   The time step number being computed can be queried using TSGetTimeStepNumber() and the total size of the step being
2757   attempted can be obtained using TSGetTimeStep(). The time at the start of the step is available via TSGetTime().
2758 
2759 .keywords: TS, timestep
2760 .seealso: TSSetPreStage(), TSSetPreStep(), TSSetPostStep(), TSGetApplicationContext()
2761 @*/
2762 PetscErrorCode  TSSetPostStage(TS ts, PetscErrorCode (*func)(TS,PetscReal,PetscInt,Vec*))
2763 {
2764   PetscFunctionBegin;
2765   PetscValidHeaderSpecific(ts, TS_CLASSID,1);
2766   ts->poststage = func;
2767   PetscFunctionReturn(0);
2768 }
2769 
2770 #undef __FUNCT__
2771 #define __FUNCT__ "TSPreStage"
2772 /*@
2773   TSPreStage - Runs the user-defined pre-stage function set using TSSetPreStage()
2774 
2775   Collective on TS
2776 
2777   Input Parameters:
2778 . ts          - The TS context obtained from TSCreate()
2779   stagetime   - The absolute time of the current stage
2780 
2781   Notes:
2782   TSPreStage() is typically used within time stepping implementations,
2783   most users would not generally call this routine themselves.
2784 
2785   Level: developer
2786 
2787 .keywords: TS, timestep
2788 .seealso: TSPostStage(), TSSetPreStep(), TSPreStep(), TSPostStep()
2789 @*/
2790 PetscErrorCode  TSPreStage(TS ts, PetscReal stagetime)
2791 {
2792   PetscErrorCode ierr;
2793 
2794   PetscFunctionBegin;
2795   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
2796   if (ts->prestage) {
2797     PetscStackCallStandard((*ts->prestage),(ts,stagetime));
2798   }
2799   PetscFunctionReturn(0);
2800 }
2801 
2802 #undef __FUNCT__
2803 #define __FUNCT__ "TSPostStage"
2804 /*@
2805   TSPostStage - Runs the user-defined post-stage function set using TSSetPostStage()
2806 
2807   Collective on TS
2808 
2809   Input Parameters:
2810 . ts          - The TS context obtained from TSCreate()
2811   stagetime   - The absolute time of the current stage
2812   stageindex  - Stage number
2813   Y           - Array of vectors (of size = total number
2814                 of stages) with the stage solutions
2815 
2816   Notes:
2817   TSPostStage() is typically used within time stepping implementations,
2818   most users would not generally call this routine themselves.
2819 
2820   Level: developer
2821 
2822 .keywords: TS, timestep
2823 .seealso: TSPreStage(), TSSetPreStep(), TSPreStep(), TSPostStep()
2824 @*/
2825 PetscErrorCode  TSPostStage(TS ts, PetscReal stagetime, PetscInt stageindex, Vec *Y)
2826 {
2827   PetscErrorCode ierr;
2828 
2829   PetscFunctionBegin;
2830   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
2831   if (ts->poststage) {
2832     PetscStackCallStandard((*ts->poststage),(ts,stagetime,stageindex,Y));
2833   }
2834   PetscFunctionReturn(0);
2835 }
2836 
2837 #undef __FUNCT__
2838 #define __FUNCT__ "TSSetPostStep"
2839 /*@C
2840   TSSetPostStep - Sets the general-purpose function
2841   called once at the end of each time step.
2842 
2843   Logically Collective on TS
2844 
2845   Input Parameters:
2846 + ts   - The TS context obtained from TSCreate()
2847 - func - The function
2848 
2849   Calling sequence of func:
2850 $ func (TS ts);
2851 
2852   Level: intermediate
2853 
2854 .keywords: TS, timestep
2855 .seealso: TSSetPreStep(), TSSetPreStage(), TSGetTimeStep(), TSGetTimeStepNumber(), TSGetTime()
2856 @*/
2857 PetscErrorCode  TSSetPostStep(TS ts, PetscErrorCode (*func)(TS))
2858 {
2859   PetscFunctionBegin;
2860   PetscValidHeaderSpecific(ts, TS_CLASSID,1);
2861   ts->poststep = func;
2862   PetscFunctionReturn(0);
2863 }
2864 
2865 #undef __FUNCT__
2866 #define __FUNCT__ "TSPostStep"
2867 /*@
2868   TSPostStep - Runs the user-defined post-step function.
2869 
2870   Collective on TS
2871 
2872   Input Parameters:
2873 . ts   - The TS context obtained from TSCreate()
2874 
2875   Notes:
2876   TSPostStep() is typically used within time stepping implementations,
2877   so most users would not generally call this routine themselves.
2878 
2879   Level: developer
2880 
2881 .keywords: TS, timestep
2882 @*/
2883 PetscErrorCode  TSPostStep(TS ts)
2884 {
2885   PetscErrorCode ierr;
2886 
2887   PetscFunctionBegin;
2888   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
2889   if (ts->poststep) {
2890     PetscStackCallStandard((*ts->poststep),(ts));
2891   }
2892   PetscFunctionReturn(0);
2893 }
2894 
2895 /* ------------ Routines to set performance monitoring options ----------- */
2896 
2897 #undef __FUNCT__
2898 #define __FUNCT__ "TSMonitorSet"
2899 /*@C
2900    TSMonitorSet - Sets an ADDITIONAL function that is to be used at every
2901    timestep to display the iteration's  progress.
2902 
2903    Logically Collective on TS
2904 
2905    Input Parameters:
2906 +  ts - the TS context obtained from TSCreate()
2907 .  monitor - monitoring routine
2908 .  mctx - [optional] user-defined context for private data for the
2909              monitor routine (use NULL if no context is desired)
2910 -  monitordestroy - [optional] routine that frees monitor context
2911           (may be NULL)
2912 
2913    Calling sequence of monitor:
2914 $    int monitor(TS ts,PetscInt steps,PetscReal time,Vec u,void *mctx)
2915 
2916 +    ts - the TS context
2917 .    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
2918                                been interpolated to)
2919 .    time - current time
2920 .    u - current iterate
2921 -    mctx - [optional] monitoring context
2922 
2923    Notes:
2924    This routine adds an additional monitor to the list of monitors that
2925    already has been loaded.
2926 
2927    Fortran notes: Only a single monitor function can be set for each TS object
2928 
2929    Level: intermediate
2930 
2931 .keywords: TS, timestep, set, monitor
2932 
2933 .seealso: TSMonitorDefault(), TSMonitorCancel()
2934 @*/
2935 PetscErrorCode  TSMonitorSet(TS ts,PetscErrorCode (*monitor)(TS,PetscInt,PetscReal,Vec,void*),void *mctx,PetscErrorCode (*mdestroy)(void**))
2936 {
2937   PetscFunctionBegin;
2938   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
2939   if (ts->numbermonitors >= MAXTSMONITORS) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Too many monitors set");
2940   ts->monitor[ts->numbermonitors]          = monitor;
2941   ts->monitordestroy[ts->numbermonitors]   = mdestroy;
2942   ts->monitorcontext[ts->numbermonitors++] = (void*)mctx;
2943   PetscFunctionReturn(0);
2944 }
2945 
2946 #undef __FUNCT__
2947 #define __FUNCT__ "TSMonitorCancel"
2948 /*@C
2949    TSMonitorCancel - Clears all the monitors that have been set on a time-step object.
2950 
2951    Logically Collective on TS
2952 
2953    Input Parameters:
2954 .  ts - the TS context obtained from TSCreate()
2955 
2956    Notes:
2957    There is no way to remove a single, specific monitor.
2958 
2959    Level: intermediate
2960 
2961 .keywords: TS, timestep, set, monitor
2962 
2963 .seealso: TSMonitorDefault(), TSMonitorSet()
2964 @*/
2965 PetscErrorCode  TSMonitorCancel(TS ts)
2966 {
2967   PetscErrorCode ierr;
2968   PetscInt       i;
2969 
2970   PetscFunctionBegin;
2971   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
2972   for (i=0; i<ts->numbermonitors; i++) {
2973     if (ts->monitordestroy[i]) {
2974       ierr = (*ts->monitordestroy[i])(&ts->monitorcontext[i]);CHKERRQ(ierr);
2975     }
2976   }
2977   ts->numbermonitors = 0;
2978   PetscFunctionReturn(0);
2979 }
2980 
2981 #undef __FUNCT__
2982 #define __FUNCT__ "TSMonitorDefault"
2983 /*@
2984    TSMonitorDefault - Sets the Default monitor
2985 
2986    Level: intermediate
2987 
2988 .keywords: TS, set, monitor
2989 
2990 .seealso: TSMonitorDefault(), TSMonitorSet()
2991 @*/
2992 PetscErrorCode TSMonitorDefault(TS ts,PetscInt step,PetscReal ptime,Vec v,void *dummy)
2993 {
2994   PetscErrorCode ierr;
2995   PetscViewer    viewer = dummy ? (PetscViewer) dummy : PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)ts));
2996 
2997   PetscFunctionBegin;
2998   ierr = PetscViewerASCIIAddTab(viewer,((PetscObject)ts)->tablevel);CHKERRQ(ierr);
2999   ierr = PetscViewerASCIIPrintf(viewer,"%D TS dt %g time %g\n",step,(double)ts->time_step,(double)ptime);CHKERRQ(ierr);
3000   ierr = PetscViewerASCIISubtractTab(viewer,((PetscObject)ts)->tablevel);CHKERRQ(ierr);
3001   PetscFunctionReturn(0);
3002 }
3003 
3004 #undef __FUNCT__
3005 #define __FUNCT__ "TSSetRetainStages"
3006 /*@
3007    TSSetRetainStages - Request that all stages in the upcoming step be stored so that interpolation will be available.
3008 
3009    Logically Collective on TS
3010 
3011    Input Argument:
3012 .  ts - time stepping context
3013 
3014    Output Argument:
3015 .  flg - PETSC_TRUE or PETSC_FALSE
3016 
3017    Level: intermediate
3018 
3019 .keywords: TS, set
3020 
3021 .seealso: TSInterpolate(), TSSetPostStep()
3022 @*/
3023 PetscErrorCode TSSetRetainStages(TS ts,PetscBool flg)
3024 {
3025   PetscFunctionBegin;
3026   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
3027   ts->retain_stages = flg;
3028   PetscFunctionReturn(0);
3029 }
3030 
3031 #undef __FUNCT__
3032 #define __FUNCT__ "TSInterpolate"
3033 /*@
3034    TSInterpolate - Interpolate the solution computed during the previous step to an arbitrary location in the interval
3035 
3036    Collective on TS
3037 
3038    Input Argument:
3039 +  ts - time stepping context
3040 -  t - time to interpolate to
3041 
3042    Output Argument:
3043 .  U - state at given time
3044 
3045    Notes:
3046    The user should call TSSetRetainStages() before taking a step in which interpolation will be requested.
3047 
3048    Level: intermediate
3049 
3050    Developer Notes:
3051    TSInterpolate() and the storing of previous steps/stages should be generalized to support delay differential equations and continuous adjoints.
3052 
3053 .keywords: TS, set
3054 
3055 .seealso: TSSetRetainStages(), TSSetPostStep()
3056 @*/
3057 PetscErrorCode TSInterpolate(TS ts,PetscReal t,Vec U)
3058 {
3059   PetscErrorCode ierr;
3060 
3061   PetscFunctionBegin;
3062   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
3063   PetscValidHeaderSpecific(U,VEC_CLASSID,3);
3064   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);
3065   if (!ts->ops->interpolate) SETERRQ1(PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"%s does not provide interpolation",((PetscObject)ts)->type_name);
3066   ierr = (*ts->ops->interpolate)(ts,t,U);CHKERRQ(ierr);
3067   PetscFunctionReturn(0);
3068 }
3069 
3070 #undef __FUNCT__
3071 #define __FUNCT__ "TSStep"
3072 /*@
3073    TSStep - Steps one time step
3074 
3075    Collective on TS
3076 
3077    Input Parameter:
3078 .  ts - the TS context obtained from TSCreate()
3079 
3080    Level: intermediate
3081 
3082    Notes:
3083    The hook set using TSSetPreStep() is called before each attempt to take the step. In general, the time step size may
3084    be changed due to adaptive error controller or solve failures. Note that steps may contain multiple stages.
3085 
3086    This may over-step the final time provided in TSSetDuration() depending on the time-step used. TSSolve() interpolates to exactly the
3087    time provided in TSSetDuration(). One can use TSInterpolate() to determine an interpolated solution within the final timestep.
3088 
3089 .keywords: TS, timestep, solve
3090 
3091 .seealso: TSCreate(), TSSetUp(), TSDestroy(), TSSolve(), TSSetPreStep(), TSSetPreStage(), TSSetPostStage(), TSInterpolate()
3092 @*/
3093 PetscErrorCode  TSStep(TS ts)
3094 {
3095   DM               dm;
3096   PetscErrorCode   ierr;
3097   static PetscBool cite = PETSC_FALSE;
3098 
3099   PetscFunctionBegin;
3100   PetscValidHeaderSpecific(ts, TS_CLASSID,1);
3101   ierr = PetscCitationsRegister("@techreport{tspaper,\n"
3102                                 "  title       = {{PETSc/TS}: A Modern Scalable {DAE/ODE} Solver Library},\n"
3103                                 "  author      = {Shrirang Abhyankar and Jed Brown and Emil Constantinescu and Debojyoti Ghosh and Barry F. Smith},\n"
3104                                 "  type        = {Preprint},\n"
3105                                 "  number      = {ANL/MCS-P5061-0114},\n"
3106                                 "  institution = {Argonne National Laboratory},\n"
3107                                 "  year        = {2014}\n}\n",&cite);
3108 
3109   ierr = TSGetDM(ts, &dm);CHKERRQ(ierr);
3110   ierr = TSSetUp(ts);CHKERRQ(ierr);
3111 
3112   ts->reason = TS_CONVERGED_ITERATING;
3113   ts->ptime_prev = ts->ptime;
3114   ierr = DMSetOutputSequenceNumber(dm, ts->steps, ts->ptime);CHKERRQ(ierr);
3115   ierr = VecViewFromOptions(ts->vec_sol, ((PetscObject) ts)->prefix, "-ts_view_solution");CHKERRQ(ierr);
3116 
3117   if (!ts->ops->step) SETERRQ1(PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"TSStep not implemented for type '%s'",((PetscObject)ts)->type_name);
3118   ierr = PetscLogEventBegin(TS_Step,ts,0,0,0);CHKERRQ(ierr);
3119   if(ts->reverse_mode) {
3120     if(!ts->ops->stepadj) {
3121       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);
3122     }else {
3123       ierr = (*ts->ops->stepadj)(ts);CHKERRQ(ierr);
3124     }
3125   }else {
3126     ierr = (*ts->ops->step)(ts);CHKERRQ(ierr);
3127   }
3128   ierr = PetscLogEventEnd(TS_Step,ts,0,0,0);CHKERRQ(ierr);
3129 
3130   ts->time_step_prev = ts->ptime - ts->ptime_prev;
3131   ierr = DMSetOutputSequenceNumber(dm, ts->steps, ts->ptime);CHKERRQ(ierr);
3132 
3133   if (ts->reason < 0) {
3134     if (ts->errorifstepfailed) {
3135       if (ts->reason == TS_DIVERGED_NONLINEAR_SOLVE) {
3136         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]);
3137       } else if (ts->reason == TS_DIVERGED_STEP_REJECTED) {
3138         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]);
3139       } else SETERRQ1(PetscObjectComm((PetscObject)ts),PETSC_ERR_NOT_CONVERGED,"TSStep has failed due to %s",TSConvergedReasons[ts->reason]);
3140     }
3141   } else if (!ts->reason) {
3142     if (ts->steps >= ts->max_steps)     ts->reason = TS_CONVERGED_ITS;
3143     else if (ts->ptime >= ts->max_time) ts->reason = TS_CONVERGED_TIME;
3144   }
3145   PetscFunctionReturn(0);
3146 }
3147 
3148 #undef __FUNCT__
3149 #define __FUNCT__ "TSEvaluateStep"
3150 /*@
3151    TSEvaluateStep - Evaluate the solution at the end of a time step with a given order of accuracy.
3152 
3153    Collective on TS
3154 
3155    Input Arguments:
3156 +  ts - time stepping context
3157 .  order - desired order of accuracy
3158 -  done - whether the step was evaluated at this order (pass NULL to generate an error if not available)
3159 
3160    Output Arguments:
3161 .  U - state at the end of the current step
3162 
3163    Level: advanced
3164 
3165    Notes:
3166    This function cannot be called until all stages have been evaluated.
3167    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.
3168 
3169 .seealso: TSStep(), TSAdapt
3170 @*/
3171 PetscErrorCode TSEvaluateStep(TS ts,PetscInt order,Vec U,PetscBool *done)
3172 {
3173   PetscErrorCode ierr;
3174 
3175   PetscFunctionBegin;
3176   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
3177   PetscValidType(ts,1);
3178   PetscValidHeaderSpecific(U,VEC_CLASSID,3);
3179   if (!ts->ops->evaluatestep) SETERRQ1(PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"TSEvaluateStep not implemented for type '%s'",((PetscObject)ts)->type_name);
3180   ierr = (*ts->ops->evaluatestep)(ts,order,U,done);CHKERRQ(ierr);
3181   PetscFunctionReturn(0);
3182 }
3183 
3184 #undef __FUNCT__
3185 #define __FUNCT__ "TSSolve"
3186 /*@
3187    TSSolve - Steps the requested number of timesteps.
3188 
3189    Collective on TS
3190 
3191    Input Parameter:
3192 +  ts - the TS context obtained from TSCreate()
3193 -  u - the solution vector  (can be null if TSSetSolution() was used, otherwise must contain the initial conditions)
3194 
3195    Level: beginner
3196 
3197    Notes:
3198    The final time returned by this function may be different from the time of the internally
3199    held state accessible by TSGetSolution() and TSGetTime() because the method may have
3200    stepped over the final time.
3201 
3202 .keywords: TS, timestep, solve
3203 
3204 .seealso: TSCreate(), TSSetSolution(), TSStep()
3205 @*/
3206 PetscErrorCode TSSolve(TS ts,Vec u)
3207 {
3208   Vec               solution;
3209   PetscErrorCode    ierr;
3210 
3211   PetscFunctionBegin;
3212   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
3213   if (u) PetscValidHeaderSpecific(u,VEC_CLASSID,2);
3214   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 */
3215     PetscValidHeaderSpecific(u,VEC_CLASSID,2);
3216     if (!ts->vec_sol || u == ts->vec_sol) {
3217       ierr = VecDuplicate(u,&solution);CHKERRQ(ierr);
3218       ierr = TSSetSolution(ts,solution);CHKERRQ(ierr);
3219       ierr = VecDestroy(&solution);CHKERRQ(ierr); /* grant ownership */
3220     }
3221     ierr = VecCopy(u,ts->vec_sol);CHKERRQ(ierr);
3222   } else if (u) {
3223     ierr = TSSetSolution(ts,u);CHKERRQ(ierr);
3224   }
3225   ierr = TSSetUp(ts);CHKERRQ(ierr); /*compute adj coefficients if the reverse mode is on*/
3226   /* reset time step and iteration counters */
3227   ts->steps             = 0;
3228   ts->ksp_its           = 0;
3229   ts->snes_its          = 0;
3230   ts->num_snes_failures = 0;
3231   ts->reject            = 0;
3232   ts->reason            = TS_CONVERGED_ITERATING;
3233 
3234   ierr = TSViewFromOptions(ts,NULL,"-ts_view_pre");CHKERRQ(ierr);
3235 
3236   if (ts->ops->solve) {         /* This private interface is transitional and should be removed when all implementations are updated. */
3237     ierr = (*ts->ops->solve)(ts);CHKERRQ(ierr);
3238     ierr = VecCopy(ts->vec_sol,u);CHKERRQ(ierr);
3239     ts->solvetime = ts->ptime;
3240   } else {
3241     /* steps the requested number of timesteps. */
3242     if (ts->steps >= ts->max_steps)     ts->reason = TS_CONVERGED_ITS;
3243     else if (!ts->reverse_mode && ts->ptime >= ts->max_time) ts->reason = TS_CONVERGED_TIME;
3244     while (!ts->reason) {
3245       if(!ts->reverse_mode) {
3246         ierr = TSMonitor(ts,ts->steps,ts->ptime,ts->vec_sol);CHKERRQ(ierr);
3247       }else {
3248         ierr = TSMonitor(ts,ts->max_steps-ts->steps,ts->ptime,ts->vec_sol);CHKERRQ(ierr);
3249       }
3250       ierr = TSStep(ts);CHKERRQ(ierr);
3251       if (ts->event) {
3252 	ierr = TSEventMonitor(ts);CHKERRQ(ierr);
3253 	if (ts->event->status != TSEVENT_PROCESSING) {
3254 	  ierr = TSPostStep(ts);CHKERRQ(ierr);
3255 	}
3256       } else {
3257 	ierr = TSPostStep(ts);CHKERRQ(ierr);
3258       }
3259     }
3260     if (!ts->reverse_mode && ts->exact_final_time == TS_EXACTFINALTIME_INTERPOLATE && ts->ptime > ts->max_time) {
3261       ierr = TSInterpolate(ts,ts->max_time,u);CHKERRQ(ierr);
3262       ts->solvetime = ts->max_time;
3263       solution = u;
3264     } else {
3265       if (u) {ierr = VecCopy(ts->vec_sol,u);CHKERRQ(ierr);}
3266       ts->solvetime = ts->ptime;
3267       solution = ts->vec_sol;
3268     }
3269     if(!ts->reverse_mode) {
3270       ierr = TSMonitor(ts,ts->steps,ts->solvetime,solution);CHKERRQ(ierr);
3271     }
3272     ierr = VecViewFromOptions(u, ((PetscObject) ts)->prefix, "-ts_view_solution");CHKERRQ(ierr);
3273   }
3274 
3275   ierr = TSViewFromOptions(ts,NULL,"-ts_view");CHKERRQ(ierr);
3276   ierr = PetscObjectSAWsBlock((PetscObject)ts);CHKERRQ(ierr);
3277   PetscFunctionReturn(0);
3278 }
3279 
3280 #undef __FUNCT__
3281 #define __FUNCT__ "TSMonitor"
3282 /*@
3283    TSMonitor - Runs all user-provided monitor routines set using TSMonitorSet()
3284 
3285    Collective on TS
3286 
3287    Input Parameters:
3288 +  ts - time stepping context obtained from TSCreate()
3289 .  step - step number that has just completed
3290 .  ptime - model time of the state
3291 -  u - state at the current model time
3292 
3293    Notes:
3294    TSMonitor() is typically used within the time stepping implementations.
3295    Users might call this function when using the TSStep() interface instead of TSSolve().
3296 
3297    Level: advanced
3298 
3299 .keywords: TS, timestep
3300 @*/
3301 PetscErrorCode TSMonitor(TS ts,PetscInt step,PetscReal ptime,Vec u)
3302 {
3303   PetscErrorCode ierr;
3304   PetscInt       i,n = ts->numbermonitors;
3305 
3306   PetscFunctionBegin;
3307   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
3308   PetscValidHeaderSpecific(u,VEC_CLASSID,4);
3309   ierr = VecLockPush(u);CHKERRQ(ierr);
3310   for (i=0; i<n; i++) {
3311     ierr = (*ts->monitor[i])(ts,step,ptime,u,ts->monitorcontext[i]);CHKERRQ(ierr);
3312   }
3313   ierr = VecLockPop(u);CHKERRQ(ierr);
3314   PetscFunctionReturn(0);
3315 }
3316 
3317 /* ------------------------------------------------------------------------*/
3318 #undef __FUNCT__
3319 #define __FUNCT__ "TSMonitorLGCtxCreate"
3320 /*@C
3321    TSMonitorLGCtxCreate - Creates a line graph context for use with
3322    TS to monitor the solution process graphically in various ways
3323 
3324    Collective on TS
3325 
3326    Input Parameters:
3327 +  host - the X display to open, or null for the local machine
3328 .  label - the title to put in the title bar
3329 .  x, y - the screen coordinates of the upper left coordinate of the window
3330 .  m, n - the screen width and height in pixels
3331 -  howoften - if positive then determines the frequency of the plotting, if -1 then only at the final time
3332 
3333    Output Parameter:
3334 .  ctx - the context
3335 
3336    Options Database Key:
3337 +  -ts_monitor_lg_timestep - automatically sets line graph monitor
3338 .  -ts_monitor_lg_solution -
3339 .  -ts_monitor_lg_error -
3340 .  -ts_monitor_lg_ksp_iterations -
3341 .  -ts_monitor_lg_snes_iterations -
3342 -  -lg_indicate_data_points <true,false> - indicate the data points (at each time step) on the plot; default is true
3343 
3344    Notes:
3345    Use TSMonitorLGCtxDestroy() to destroy.
3346 
3347    Level: intermediate
3348 
3349 .keywords: TS, monitor, line graph, residual, seealso
3350 
3351 .seealso: TSMonitorLGTimeStep(), TSMonitorSet(), TSMonitorLGSolution(), TSMonitorLGError()
3352 
3353 @*/
3354 PetscErrorCode  TSMonitorLGCtxCreate(MPI_Comm comm,const char host[],const char label[],int x,int y,int m,int n,PetscInt howoften,TSMonitorLGCtx *ctx)
3355 {
3356   PetscDraw      win;
3357   PetscErrorCode ierr;
3358 
3359   PetscFunctionBegin;
3360   ierr = PetscNew(ctx);CHKERRQ(ierr);
3361   ierr = PetscDrawCreate(comm,host,label,x,y,m,n,&win);CHKERRQ(ierr);
3362   ierr = PetscDrawSetFromOptions(win);CHKERRQ(ierr);
3363   ierr = PetscDrawLGCreate(win,1,&(*ctx)->lg);CHKERRQ(ierr);
3364   ierr = PetscLogObjectParent((PetscObject)(*ctx)->lg,(PetscObject)win);CHKERRQ(ierr);
3365   ierr = PetscDrawLGIndicateDataPoints((*ctx)->lg,PETSC_TRUE);CHKERRQ(ierr);
3366   ierr = PetscDrawLGSetFromOptions((*ctx)->lg);CHKERRQ(ierr);
3367   (*ctx)->howoften = howoften;
3368   PetscFunctionReturn(0);
3369 }
3370 
3371 #undef __FUNCT__
3372 #define __FUNCT__ "TSMonitorLGTimeStep"
3373 PetscErrorCode TSMonitorLGTimeStep(TS ts,PetscInt step,PetscReal ptime,Vec v,void *monctx)
3374 {
3375   TSMonitorLGCtx ctx = (TSMonitorLGCtx) monctx;
3376   PetscReal      x   = ptime,y;
3377   PetscErrorCode ierr;
3378 
3379   PetscFunctionBegin;
3380   if (!step) {
3381     PetscDrawAxis axis;
3382     ierr = PetscDrawLGGetAxis(ctx->lg,&axis);CHKERRQ(ierr);
3383     ierr = PetscDrawAxisSetLabels(axis,"Timestep as function of time","Time","Time step");CHKERRQ(ierr);
3384     ierr = PetscDrawLGReset(ctx->lg);CHKERRQ(ierr);
3385     ierr = PetscDrawLGIndicateDataPoints(ctx->lg,PETSC_TRUE);CHKERRQ(ierr);
3386   }
3387   ierr = TSGetTimeStep(ts,&y);CHKERRQ(ierr);
3388   ierr = PetscDrawLGAddPoint(ctx->lg,&x,&y);CHKERRQ(ierr);
3389   if (((ctx->howoften > 0) && (!(step % ctx->howoften))) || ((ctx->howoften == -1) && ts->reason)) {
3390     ierr = PetscDrawLGDraw(ctx->lg);CHKERRQ(ierr);
3391   }
3392   PetscFunctionReturn(0);
3393 }
3394 
3395 #undef __FUNCT__
3396 #define __FUNCT__ "TSMonitorLGCtxDestroy"
3397 /*@C
3398    TSMonitorLGCtxDestroy - Destroys a line graph context that was created
3399    with TSMonitorLGCtxCreate().
3400 
3401    Collective on TSMonitorLGCtx
3402 
3403    Input Parameter:
3404 .  ctx - the monitor context
3405 
3406    Level: intermediate
3407 
3408 .keywords: TS, monitor, line graph, destroy
3409 
3410 .seealso: TSMonitorLGCtxCreate(),  TSMonitorSet(), TSMonitorLGTimeStep();
3411 @*/
3412 PetscErrorCode  TSMonitorLGCtxDestroy(TSMonitorLGCtx *ctx)
3413 {
3414   PetscDraw      draw;
3415   PetscErrorCode ierr;
3416 
3417   PetscFunctionBegin;
3418   ierr = PetscDrawLGGetDraw((*ctx)->lg,&draw);CHKERRQ(ierr);
3419   ierr = PetscDrawDestroy(&draw);CHKERRQ(ierr);
3420   ierr = PetscDrawLGDestroy(&(*ctx)->lg);CHKERRQ(ierr);
3421   ierr = PetscFree(*ctx);CHKERRQ(ierr);
3422   PetscFunctionReturn(0);
3423 }
3424 
3425 #undef __FUNCT__
3426 #define __FUNCT__ "TSGetTime"
3427 /*@
3428    TSGetTime - Gets the time of the most recently completed step.
3429 
3430    Not Collective
3431 
3432    Input Parameter:
3433 .  ts - the TS context obtained from TSCreate()
3434 
3435    Output Parameter:
3436 .  t  - the current time
3437 
3438    Level: beginner
3439 
3440    Note:
3441    When called during time step evaluation (e.g. during residual evaluation or via hooks set using TSSetPreStep(),
3442    TSSetPreStage(), TSSetPostStage(), or TSSetPostStep()), the time is the time at the start of the step being evaluated.
3443 
3444 .seealso: TSSetInitialTimeStep(), TSGetTimeStep()
3445 
3446 .keywords: TS, get, time
3447 @*/
3448 PetscErrorCode  TSGetTime(TS ts,PetscReal *t)
3449 {
3450   PetscFunctionBegin;
3451   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
3452   PetscValidRealPointer(t,2);
3453   *t = ts->ptime;
3454   PetscFunctionReturn(0);
3455 }
3456 
3457 #undef __FUNCT__
3458 #define __FUNCT__ "TSGetPrevTime"
3459 /*@
3460    TSGetPrevTime - Gets the starting time of the previously completed step.
3461 
3462    Not Collective
3463 
3464    Input Parameter:
3465 .  ts - the TS context obtained from TSCreate()
3466 
3467    Output Parameter:
3468 .  t  - the previous time
3469 
3470    Level: beginner
3471 
3472 .seealso: TSSetInitialTimeStep(), TSGetTimeStep()
3473 
3474 .keywords: TS, get, time
3475 @*/
3476 PetscErrorCode  TSGetPrevTime(TS ts,PetscReal *t)
3477 {
3478   PetscFunctionBegin;
3479   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
3480   PetscValidRealPointer(t,2);
3481   *t = ts->ptime_prev;
3482   PetscFunctionReturn(0);
3483 }
3484 
3485 #undef __FUNCT__
3486 #define __FUNCT__ "TSSetTime"
3487 /*@
3488    TSSetTime - Allows one to reset the time.
3489 
3490    Logically Collective on TS
3491 
3492    Input Parameters:
3493 +  ts - the TS context obtained from TSCreate()
3494 -  time - the time
3495 
3496    Level: intermediate
3497 
3498 .seealso: TSGetTime(), TSSetDuration()
3499 
3500 .keywords: TS, set, time
3501 @*/
3502 PetscErrorCode  TSSetTime(TS ts, PetscReal t)
3503 {
3504   PetscFunctionBegin;
3505   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
3506   PetscValidLogicalCollectiveReal(ts,t,2);
3507   ts->ptime = t;
3508   PetscFunctionReturn(0);
3509 }
3510 
3511 #undef __FUNCT__
3512 #define __FUNCT__ "TSSetOptionsPrefix"
3513 /*@C
3514    TSSetOptionsPrefix - Sets the prefix used for searching for all
3515    TS options in the database.
3516 
3517    Logically Collective on TS
3518 
3519    Input Parameter:
3520 +  ts     - The TS context
3521 -  prefix - The prefix to prepend to all option names
3522 
3523    Notes:
3524    A hyphen (-) must NOT be given at the beginning of the prefix name.
3525    The first character of all runtime options is AUTOMATICALLY the
3526    hyphen.
3527 
3528    Level: advanced
3529 
3530 .keywords: TS, set, options, prefix, database
3531 
3532 .seealso: TSSetFromOptions()
3533 
3534 @*/
3535 PetscErrorCode  TSSetOptionsPrefix(TS ts,const char prefix[])
3536 {
3537   PetscErrorCode ierr;
3538   SNES           snes;
3539 
3540   PetscFunctionBegin;
3541   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
3542   ierr = PetscObjectSetOptionsPrefix((PetscObject)ts,prefix);CHKERRQ(ierr);
3543   ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr);
3544   ierr = SNESSetOptionsPrefix(snes,prefix);CHKERRQ(ierr);
3545   PetscFunctionReturn(0);
3546 }
3547 
3548 
3549 #undef __FUNCT__
3550 #define __FUNCT__ "TSAppendOptionsPrefix"
3551 /*@C
3552    TSAppendOptionsPrefix - Appends to the prefix used for searching for all
3553    TS options in the database.
3554 
3555    Logically Collective on TS
3556 
3557    Input Parameter:
3558 +  ts     - The TS context
3559 -  prefix - The prefix to prepend to all option names
3560 
3561    Notes:
3562    A hyphen (-) must NOT be given at the beginning of the prefix name.
3563    The first character of all runtime options is AUTOMATICALLY the
3564    hyphen.
3565 
3566    Level: advanced
3567 
3568 .keywords: TS, append, options, prefix, database
3569 
3570 .seealso: TSGetOptionsPrefix()
3571 
3572 @*/
3573 PetscErrorCode  TSAppendOptionsPrefix(TS ts,const char prefix[])
3574 {
3575   PetscErrorCode ierr;
3576   SNES           snes;
3577 
3578   PetscFunctionBegin;
3579   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
3580   ierr = PetscObjectAppendOptionsPrefix((PetscObject)ts,prefix);CHKERRQ(ierr);
3581   ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr);
3582   ierr = SNESAppendOptionsPrefix(snes,prefix);CHKERRQ(ierr);
3583   PetscFunctionReturn(0);
3584 }
3585 
3586 #undef __FUNCT__
3587 #define __FUNCT__ "TSGetOptionsPrefix"
3588 /*@C
3589    TSGetOptionsPrefix - Sets the prefix used for searching for all
3590    TS options in the database.
3591 
3592    Not Collective
3593 
3594    Input Parameter:
3595 .  ts - The TS context
3596 
3597    Output Parameter:
3598 .  prefix - A pointer to the prefix string used
3599 
3600    Notes: On the fortran side, the user should pass in a string 'prifix' of
3601    sufficient length to hold the prefix.
3602 
3603    Level: intermediate
3604 
3605 .keywords: TS, get, options, prefix, database
3606 
3607 .seealso: TSAppendOptionsPrefix()
3608 @*/
3609 PetscErrorCode  TSGetOptionsPrefix(TS ts,const char *prefix[])
3610 {
3611   PetscErrorCode ierr;
3612 
3613   PetscFunctionBegin;
3614   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
3615   PetscValidPointer(prefix,2);
3616   ierr = PetscObjectGetOptionsPrefix((PetscObject)ts,prefix);CHKERRQ(ierr);
3617   PetscFunctionReturn(0);
3618 }
3619 
3620 #undef __FUNCT__
3621 #define __FUNCT__ "TSGetRHSJacobian"
3622 /*@C
3623    TSGetRHSJacobian - Returns the Jacobian J at the present timestep.
3624 
3625    Not Collective, but parallel objects are returned if TS is parallel
3626 
3627    Input Parameter:
3628 .  ts  - The TS context obtained from TSCreate()
3629 
3630    Output Parameters:
3631 +  Amat - The (approximate) Jacobian J of G, where U_t = G(U,t)  (or NULL)
3632 .  Pmat - The matrix from which the preconditioner is constructed, usually the same as Amat  (or NULL)
3633 .  func - Function to compute the Jacobian of the RHS  (or NULL)
3634 -  ctx - User-defined context for Jacobian evaluation routine  (or NULL)
3635 
3636    Notes: You can pass in NULL for any return argument you do not need.
3637 
3638    Level: intermediate
3639 
3640 .seealso: TSGetTimeStep(), TSGetMatrices(), TSGetTime(), TSGetTimeStepNumber()
3641 
3642 .keywords: TS, timestep, get, matrix, Jacobian
3643 @*/
3644 PetscErrorCode  TSGetRHSJacobian(TS ts,Mat *Amat,Mat *Pmat,TSRHSJacobian *func,void **ctx)
3645 {
3646   PetscErrorCode ierr;
3647   SNES           snes;
3648   DM             dm;
3649 
3650   PetscFunctionBegin;
3651   ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr);
3652   ierr = SNESGetJacobian(snes,Amat,Pmat,NULL,NULL);CHKERRQ(ierr);
3653   ierr = TSGetDM(ts,&dm);CHKERRQ(ierr);
3654   ierr = DMTSGetRHSJacobian(dm,func,ctx);CHKERRQ(ierr);
3655   PetscFunctionReturn(0);
3656 }
3657 
3658 #undef __FUNCT__
3659 #define __FUNCT__ "TSGetIJacobian"
3660 /*@C
3661    TSGetIJacobian - Returns the implicit Jacobian at the present timestep.
3662 
3663    Not Collective, but parallel objects are returned if TS is parallel
3664 
3665    Input Parameter:
3666 .  ts  - The TS context obtained from TSCreate()
3667 
3668    Output Parameters:
3669 +  Amat  - The (approximate) Jacobian of F(t,U,U_t)
3670 .  Pmat - The matrix from which the preconditioner is constructed, often the same as Amat
3671 .  f   - The function to compute the matrices
3672 - ctx - User-defined context for Jacobian evaluation routine
3673 
3674    Notes: You can pass in NULL for any return argument you do not need.
3675 
3676    Level: advanced
3677 
3678 .seealso: TSGetTimeStep(), TSGetRHSJacobian(), TSGetMatrices(), TSGetTime(), TSGetTimeStepNumber()
3679 
3680 .keywords: TS, timestep, get, matrix, Jacobian
3681 @*/
3682 PetscErrorCode  TSGetIJacobian(TS ts,Mat *Amat,Mat *Pmat,TSIJacobian *f,void **ctx)
3683 {
3684   PetscErrorCode ierr;
3685   SNES           snes;
3686   DM             dm;
3687 
3688   PetscFunctionBegin;
3689   ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr);
3690   ierr = SNESSetUpMatrices(snes);CHKERRQ(ierr);
3691   ierr = SNESGetJacobian(snes,Amat,Pmat,NULL,NULL);CHKERRQ(ierr);
3692   ierr = TSGetDM(ts,&dm);CHKERRQ(ierr);
3693   ierr = DMTSGetIJacobian(dm,f,ctx);CHKERRQ(ierr);
3694   PetscFunctionReturn(0);
3695 }
3696 
3697 
3698 #undef __FUNCT__
3699 #define __FUNCT__ "TSMonitorDrawSolution"
3700 /*@C
3701    TSMonitorDrawSolution - Monitors progress of the TS solvers by calling
3702    VecView() for the solution at each timestep
3703 
3704    Collective on TS
3705 
3706    Input Parameters:
3707 +  ts - the TS context
3708 .  step - current time-step
3709 .  ptime - current time
3710 -  dummy - either a viewer or NULL
3711 
3712    Options Database:
3713 .   -ts_monitor_draw_solution_initial - show initial solution as well as current solution
3714 
3715    Notes: the initial solution and current solution are not displayed with a common axis scaling so generally the option -ts_monitor_draw_solution_initial
3716        will look bad
3717 
3718    Level: intermediate
3719 
3720 .keywords: TS,  vector, monitor, view
3721 
3722 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView()
3723 @*/
3724 PetscErrorCode  TSMonitorDrawSolution(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dummy)
3725 {
3726   PetscErrorCode   ierr;
3727   TSMonitorDrawCtx ictx = (TSMonitorDrawCtx)dummy;
3728   PetscDraw        draw;
3729 
3730   PetscFunctionBegin;
3731   if (!step && ictx->showinitial) {
3732     if (!ictx->initialsolution) {
3733       ierr = VecDuplicate(u,&ictx->initialsolution);CHKERRQ(ierr);
3734     }
3735     ierr = VecCopy(u,ictx->initialsolution);CHKERRQ(ierr);
3736   }
3737   if (!(((ictx->howoften > 0) && (!(step % ictx->howoften))) || ((ictx->howoften == -1) && ts->reason))) PetscFunctionReturn(0);
3738 
3739   if (ictx->showinitial) {
3740     PetscReal pause;
3741     ierr = PetscViewerDrawGetPause(ictx->viewer,&pause);CHKERRQ(ierr);
3742     ierr = PetscViewerDrawSetPause(ictx->viewer,0.0);CHKERRQ(ierr);
3743     ierr = VecView(ictx->initialsolution,ictx->viewer);CHKERRQ(ierr);
3744     ierr = PetscViewerDrawSetPause(ictx->viewer,pause);CHKERRQ(ierr);
3745     ierr = PetscViewerDrawSetHold(ictx->viewer,PETSC_TRUE);CHKERRQ(ierr);
3746   }
3747   ierr = VecView(u,ictx->viewer);CHKERRQ(ierr);
3748   if (ictx->showtimestepandtime) {
3749     PetscReal xl,yl,xr,yr,tw,w,h;
3750     char      time[32];
3751     size_t    len;
3752 
3753     ierr = PetscViewerDrawGetDraw(ictx->viewer,0,&draw);CHKERRQ(ierr);
3754     ierr = PetscSNPrintf(time,32,"Timestep %d Time %f",(int)step,(double)ptime);CHKERRQ(ierr);
3755     ierr = PetscDrawGetCoordinates(draw,&xl,&yl,&xr,&yr);CHKERRQ(ierr);
3756     ierr =  PetscStrlen(time,&len);CHKERRQ(ierr);
3757     ierr = PetscDrawStringGetSize(draw,&tw,NULL);CHKERRQ(ierr);
3758     w    = xl + .5*(xr - xl) - .5*len*tw;
3759     h    = yl + .95*(yr - yl);
3760     ierr = PetscDrawString(draw,w,h,PETSC_DRAW_BLACK,time);CHKERRQ(ierr);
3761     ierr = PetscDrawFlush(draw);CHKERRQ(ierr);
3762   }
3763 
3764   if (ictx->showinitial) {
3765     ierr = PetscViewerDrawSetHold(ictx->viewer,PETSC_FALSE);CHKERRQ(ierr);
3766   }
3767   PetscFunctionReturn(0);
3768 }
3769 
3770 #undef __FUNCT__
3771 #define __FUNCT__ "TSMonitorDrawSolutionPhase"
3772 /*@C
3773    TSMonitorDrawSolutionPhase - Monitors progress of the TS solvers by plotting the solution as a phase diagram
3774 
3775    Collective on TS
3776 
3777    Input Parameters:
3778 +  ts - the TS context
3779 .  step - current time-step
3780 .  ptime - current time
3781 -  dummy - either a viewer or NULL
3782 
3783    Level: intermediate
3784 
3785 .keywords: TS,  vector, monitor, view
3786 
3787 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView()
3788 @*/
3789 PetscErrorCode  TSMonitorDrawSolutionPhase(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dummy)
3790 {
3791   PetscErrorCode    ierr;
3792   TSMonitorDrawCtx  ictx = (TSMonitorDrawCtx)dummy;
3793   PetscDraw         draw;
3794   MPI_Comm          comm;
3795   PetscInt          n;
3796   PetscMPIInt       size;
3797   PetscReal         xl,yl,xr,yr,tw,w,h;
3798   char              time[32];
3799   size_t            len;
3800   const PetscScalar *U;
3801 
3802   PetscFunctionBegin;
3803   ierr = PetscObjectGetComm((PetscObject)ts,&comm);CHKERRQ(ierr);
3804   ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
3805   if (size != 1) SETERRQ(comm,PETSC_ERR_SUP,"Only allowed for sequential runs");
3806   ierr = VecGetSize(u,&n);CHKERRQ(ierr);
3807   if (n != 2) SETERRQ(comm,PETSC_ERR_SUP,"Only for ODEs with two unknowns");
3808 
3809   ierr = PetscViewerDrawGetDraw(ictx->viewer,0,&draw);CHKERRQ(ierr);
3810 
3811   ierr = VecGetArrayRead(u,&U);CHKERRQ(ierr);
3812   ierr = PetscDrawAxisGetLimits(ictx->axis,&xl,&xr,&yl,&yr);CHKERRQ(ierr);
3813   if ((PetscRealPart(U[0]) < xl) || (PetscRealPart(U[1]) < yl) || (PetscRealPart(U[0]) > xr) || (PetscRealPart(U[1]) > yr)) {
3814       ierr = VecRestoreArrayRead(u,&U);CHKERRQ(ierr);
3815       PetscFunctionReturn(0);
3816   }
3817   if (!step) ictx->color++;
3818   ierr = PetscDrawPoint(draw,PetscRealPart(U[0]),PetscRealPart(U[1]),ictx->color);CHKERRQ(ierr);
3819   ierr = VecRestoreArrayRead(u,&U);CHKERRQ(ierr);
3820 
3821   if (ictx->showtimestepandtime) {
3822     ierr = PetscDrawGetCoordinates(draw,&xl,&yl,&xr,&yr);CHKERRQ(ierr);
3823     ierr = PetscSNPrintf(time,32,"Timestep %d Time %f",(int)step,(double)ptime);CHKERRQ(ierr);
3824     ierr = PetscStrlen(time,&len);CHKERRQ(ierr);
3825     ierr = PetscDrawStringGetSize(draw,&tw,NULL);CHKERRQ(ierr);
3826     w    = xl + .5*(xr - xl) - .5*len*tw;
3827     h    = yl + .95*(yr - yl);
3828     ierr = PetscDrawString(draw,w,h,PETSC_DRAW_BLACK,time);CHKERRQ(ierr);
3829   }
3830   ierr = PetscDrawFlush(draw);CHKERRQ(ierr);
3831   PetscFunctionReturn(0);
3832 }
3833 
3834 
3835 #undef __FUNCT__
3836 #define __FUNCT__ "TSMonitorDrawCtxDestroy"
3837 /*@C
3838    TSMonitorDrawCtxDestroy - Destroys the monitor context for TSMonitorDrawSolution()
3839 
3840    Collective on TS
3841 
3842    Input Parameters:
3843 .    ctx - the monitor context
3844 
3845    Level: intermediate
3846 
3847 .keywords: TS,  vector, monitor, view
3848 
3849 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorDrawSolution(), TSMonitorDrawError()
3850 @*/
3851 PetscErrorCode  TSMonitorDrawCtxDestroy(TSMonitorDrawCtx *ictx)
3852 {
3853   PetscErrorCode ierr;
3854 
3855   PetscFunctionBegin;
3856   ierr = PetscDrawAxisDestroy(&(*ictx)->axis);CHKERRQ(ierr);
3857   ierr = PetscViewerDestroy(&(*ictx)->viewer);CHKERRQ(ierr);
3858   ierr = VecDestroy(&(*ictx)->initialsolution);CHKERRQ(ierr);
3859   ierr = PetscFree(*ictx);CHKERRQ(ierr);
3860   PetscFunctionReturn(0);
3861 }
3862 
3863 #undef __FUNCT__
3864 #define __FUNCT__ "TSMonitorDrawCtxCreate"
3865 /*@C
3866    TSMonitorDrawCtxCreate - Creates the monitor context for TSMonitorDrawCtx
3867 
3868    Collective on TS
3869 
3870    Input Parameter:
3871 .    ts - time-step context
3872 
3873    Output Patameter:
3874 .    ctx - the monitor context
3875 
3876    Options Database:
3877 .   -ts_monitor_draw_solution_initial - show initial solution as well as current solution
3878 
3879    Level: intermediate
3880 
3881 .keywords: TS,  vector, monitor, view
3882 
3883 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorDrawCtx()
3884 @*/
3885 PetscErrorCode  TSMonitorDrawCtxCreate(MPI_Comm comm,const char host[],const char label[],int x,int y,int m,int n,PetscInt howoften,TSMonitorDrawCtx *ctx)
3886 {
3887   PetscErrorCode   ierr;
3888 
3889   PetscFunctionBegin;
3890   ierr = PetscNew(ctx);CHKERRQ(ierr);
3891   ierr = PetscViewerDrawOpen(comm,host,label,x,y,m,n,&(*ctx)->viewer);CHKERRQ(ierr);
3892   ierr = PetscViewerSetFromOptions((*ctx)->viewer);CHKERRQ(ierr);
3893 
3894   (*ctx)->howoften    = howoften;
3895   (*ctx)->showinitial = PETSC_FALSE;
3896   ierr = PetscOptionsGetBool(NULL,"-ts_monitor_draw_solution_initial",&(*ctx)->showinitial,NULL);CHKERRQ(ierr);
3897 
3898   (*ctx)->showtimestepandtime = PETSC_FALSE;
3899   ierr = PetscOptionsGetBool(NULL,"-ts_monitor_draw_solution_show_time",&(*ctx)->showtimestepandtime,NULL);CHKERRQ(ierr);
3900   (*ctx)->color = PETSC_DRAW_WHITE;
3901   PetscFunctionReturn(0);
3902 }
3903 
3904 #undef __FUNCT__
3905 #define __FUNCT__ "TSMonitorDrawError"
3906 /*@C
3907    TSMonitorDrawError - Monitors progress of the TS solvers by calling
3908    VecView() for the error at each timestep
3909 
3910    Collective on TS
3911 
3912    Input Parameters:
3913 +  ts - the TS context
3914 .  step - current time-step
3915 .  ptime - current time
3916 -  dummy - either a viewer or NULL
3917 
3918    Level: intermediate
3919 
3920 .keywords: TS,  vector, monitor, view
3921 
3922 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView()
3923 @*/
3924 PetscErrorCode  TSMonitorDrawError(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dummy)
3925 {
3926   PetscErrorCode   ierr;
3927   TSMonitorDrawCtx ctx    = (TSMonitorDrawCtx)dummy;
3928   PetscViewer      viewer = ctx->viewer;
3929   Vec              work;
3930 
3931   PetscFunctionBegin;
3932   if (!(((ctx->howoften > 0) && (!(step % ctx->howoften))) || ((ctx->howoften == -1) && ts->reason))) PetscFunctionReturn(0);
3933   ierr = VecDuplicate(u,&work);CHKERRQ(ierr);
3934   ierr = TSComputeSolutionFunction(ts,ptime,work);CHKERRQ(ierr);
3935   ierr = VecAXPY(work,-1.0,u);CHKERRQ(ierr);
3936   ierr = VecView(work,viewer);CHKERRQ(ierr);
3937   ierr = VecDestroy(&work);CHKERRQ(ierr);
3938   PetscFunctionReturn(0);
3939 }
3940 
3941 #include <petsc-private/dmimpl.h>
3942 #undef __FUNCT__
3943 #define __FUNCT__ "TSSetDM"
3944 /*@
3945    TSSetDM - Sets the DM that may be used by some preconditioners
3946 
3947    Logically Collective on TS and DM
3948 
3949    Input Parameters:
3950 +  ts - the preconditioner context
3951 -  dm - the dm
3952 
3953    Level: intermediate
3954 
3955 
3956 .seealso: TSGetDM(), SNESSetDM(), SNESGetDM()
3957 @*/
3958 PetscErrorCode  TSSetDM(TS ts,DM dm)
3959 {
3960   PetscErrorCode ierr;
3961   SNES           snes;
3962   DMTS           tsdm;
3963 
3964   PetscFunctionBegin;
3965   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
3966   ierr = PetscObjectReference((PetscObject)dm);CHKERRQ(ierr);
3967   if (ts->dm) {               /* Move the DMTS context over to the new DM unless the new DM already has one */
3968     if (ts->dm->dmts && !dm->dmts) {
3969       ierr = DMCopyDMTS(ts->dm,dm);CHKERRQ(ierr);
3970       ierr = DMGetDMTS(ts->dm,&tsdm);CHKERRQ(ierr);
3971       if (tsdm->originaldm == ts->dm) { /* Grant write privileges to the replacement DM */
3972         tsdm->originaldm = dm;
3973       }
3974     }
3975     ierr = DMDestroy(&ts->dm);CHKERRQ(ierr);
3976   }
3977   ts->dm = dm;
3978 
3979   ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr);
3980   ierr = SNESSetDM(snes,dm);CHKERRQ(ierr);
3981   PetscFunctionReturn(0);
3982 }
3983 
3984 #undef __FUNCT__
3985 #define __FUNCT__ "TSGetDM"
3986 /*@
3987    TSGetDM - Gets the DM that may be used by some preconditioners
3988 
3989    Not Collective
3990 
3991    Input Parameter:
3992 . ts - the preconditioner context
3993 
3994    Output Parameter:
3995 .  dm - the dm
3996 
3997    Level: intermediate
3998 
3999 
4000 .seealso: TSSetDM(), SNESSetDM(), SNESGetDM()
4001 @*/
4002 PetscErrorCode  TSGetDM(TS ts,DM *dm)
4003 {
4004   PetscErrorCode ierr;
4005 
4006   PetscFunctionBegin;
4007   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
4008   if (!ts->dm) {
4009     ierr = DMShellCreate(PetscObjectComm((PetscObject)ts),&ts->dm);CHKERRQ(ierr);
4010     if (ts->snes) {ierr = SNESSetDM(ts->snes,ts->dm);CHKERRQ(ierr);}
4011   }
4012   *dm = ts->dm;
4013   PetscFunctionReturn(0);
4014 }
4015 
4016 #undef __FUNCT__
4017 #define __FUNCT__ "SNESTSFormFunction"
4018 /*@
4019    SNESTSFormFunction - Function to evaluate nonlinear residual
4020 
4021    Logically Collective on SNES
4022 
4023    Input Parameter:
4024 + snes - nonlinear solver
4025 . U - the current state at which to evaluate the residual
4026 - ctx - user context, must be a TS
4027 
4028    Output Parameter:
4029 . F - the nonlinear residual
4030 
4031    Notes:
4032    This function is not normally called by users and is automatically registered with the SNES used by TS.
4033    It is most frequently passed to MatFDColoringSetFunction().
4034 
4035    Level: advanced
4036 
4037 .seealso: SNESSetFunction(), MatFDColoringSetFunction()
4038 @*/
4039 PetscErrorCode  SNESTSFormFunction(SNES snes,Vec U,Vec F,void *ctx)
4040 {
4041   TS             ts = (TS)ctx;
4042   PetscErrorCode ierr;
4043 
4044   PetscFunctionBegin;
4045   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
4046   PetscValidHeaderSpecific(U,VEC_CLASSID,2);
4047   PetscValidHeaderSpecific(F,VEC_CLASSID,3);
4048   PetscValidHeaderSpecific(ts,TS_CLASSID,4);
4049   ierr = (ts->ops->snesfunction)(snes,U,F,ts);CHKERRQ(ierr);
4050   PetscFunctionReturn(0);
4051 }
4052 
4053 #undef __FUNCT__
4054 #define __FUNCT__ "SNESTSFormJacobian"
4055 /*@
4056    SNESTSFormJacobian - Function to evaluate the Jacobian
4057 
4058    Collective on SNES
4059 
4060    Input Parameter:
4061 + snes - nonlinear solver
4062 . U - the current state at which to evaluate the residual
4063 - ctx - user context, must be a TS
4064 
4065    Output Parameter:
4066 + A - the Jacobian
4067 . B - the preconditioning matrix (may be the same as A)
4068 - flag - indicates any structure change in the matrix
4069 
4070    Notes:
4071    This function is not normally called by users and is automatically registered with the SNES used by TS.
4072 
4073    Level: developer
4074 
4075 .seealso: SNESSetJacobian()
4076 @*/
4077 PetscErrorCode  SNESTSFormJacobian(SNES snes,Vec U,Mat A,Mat B,void *ctx)
4078 {
4079   TS             ts = (TS)ctx;
4080   PetscErrorCode ierr;
4081 
4082   PetscFunctionBegin;
4083   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
4084   PetscValidHeaderSpecific(U,VEC_CLASSID,2);
4085   PetscValidPointer(A,3);
4086   PetscValidHeaderSpecific(A,MAT_CLASSID,3);
4087   PetscValidPointer(B,4);
4088   PetscValidHeaderSpecific(B,MAT_CLASSID,4);
4089   PetscValidHeaderSpecific(ts,TS_CLASSID,6);
4090   ierr = (ts->ops->snesjacobian)(snes,U,A,B,ts);CHKERRQ(ierr);
4091   PetscFunctionReturn(0);
4092 }
4093 
4094 #undef __FUNCT__
4095 #define __FUNCT__ "TSComputeRHSFunctionLinear"
4096 /*@C
4097    TSComputeRHSFunctionLinear - Evaluate the right hand side via the user-provided Jacobian, for linear problems only
4098 
4099    Collective on TS
4100 
4101    Input Arguments:
4102 +  ts - time stepping context
4103 .  t - time at which to evaluate
4104 .  U - state at which to evaluate
4105 -  ctx - context
4106 
4107    Output Arguments:
4108 .  F - right hand side
4109 
4110    Level: intermediate
4111 
4112    Notes:
4113    This function is intended to be passed to TSSetRHSFunction() to evaluate the right hand side for linear problems.
4114    The matrix (and optionally the evaluation context) should be passed to TSSetRHSJacobian().
4115 
4116 .seealso: TSSetRHSFunction(), TSSetRHSJacobian(), TSComputeRHSJacobianConstant()
4117 @*/
4118 PetscErrorCode TSComputeRHSFunctionLinear(TS ts,PetscReal t,Vec U,Vec F,void *ctx)
4119 {
4120   PetscErrorCode ierr;
4121   Mat            Arhs,Brhs;
4122 
4123   PetscFunctionBegin;
4124   ierr = TSGetRHSMats_Private(ts,&Arhs,&Brhs);CHKERRQ(ierr);
4125   ierr = TSComputeRHSJacobian(ts,t,U,Arhs,Brhs);CHKERRQ(ierr);
4126   ierr = MatMult(Arhs,U,F);CHKERRQ(ierr);
4127   PetscFunctionReturn(0);
4128 }
4129 
4130 #undef __FUNCT__
4131 #define __FUNCT__ "TSComputeRHSJacobianConstant"
4132 /*@C
4133    TSComputeRHSJacobianConstant - Reuses a Jacobian that is time-independent.
4134 
4135    Collective on TS
4136 
4137    Input Arguments:
4138 +  ts - time stepping context
4139 .  t - time at which to evaluate
4140 .  U - state at which to evaluate
4141 -  ctx - context
4142 
4143    Output Arguments:
4144 +  A - pointer to operator
4145 .  B - pointer to preconditioning matrix
4146 -  flg - matrix structure flag
4147 
4148    Level: intermediate
4149 
4150    Notes:
4151    This function is intended to be passed to TSSetRHSJacobian() to evaluate the Jacobian for linear time-independent problems.
4152 
4153 .seealso: TSSetRHSFunction(), TSSetRHSJacobian(), TSComputeRHSFunctionLinear()
4154 @*/
4155 PetscErrorCode TSComputeRHSJacobianConstant(TS ts,PetscReal t,Vec U,Mat A,Mat B,void *ctx)
4156 {
4157   PetscFunctionBegin;
4158   PetscFunctionReturn(0);
4159 }
4160 
4161 #undef __FUNCT__
4162 #define __FUNCT__ "TSComputeIFunctionLinear"
4163 /*@C
4164    TSComputeIFunctionLinear - Evaluate the left hand side via the user-provided Jacobian, for linear problems only
4165 
4166    Collective on TS
4167 
4168    Input Arguments:
4169 +  ts - time stepping context
4170 .  t - time at which to evaluate
4171 .  U - state at which to evaluate
4172 .  Udot - time derivative of state vector
4173 -  ctx - context
4174 
4175    Output Arguments:
4176 .  F - left hand side
4177 
4178    Level: intermediate
4179 
4180    Notes:
4181    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
4182    user is required to write their own TSComputeIFunction.
4183    This function is intended to be passed to TSSetIFunction() to evaluate the left hand side for linear problems.
4184    The matrix (and optionally the evaluation context) should be passed to TSSetIJacobian().
4185 
4186 .seealso: TSSetIFunction(), TSSetIJacobian(), TSComputeIJacobianConstant()
4187 @*/
4188 PetscErrorCode TSComputeIFunctionLinear(TS ts,PetscReal t,Vec U,Vec Udot,Vec F,void *ctx)
4189 {
4190   PetscErrorCode ierr;
4191   Mat            A,B;
4192 
4193   PetscFunctionBegin;
4194   ierr = TSGetIJacobian(ts,&A,&B,NULL,NULL);CHKERRQ(ierr);
4195   ierr = TSComputeIJacobian(ts,t,U,Udot,1.0,A,B,PETSC_TRUE);CHKERRQ(ierr);
4196   ierr = MatMult(A,Udot,F);CHKERRQ(ierr);
4197   PetscFunctionReturn(0);
4198 }
4199 
4200 #undef __FUNCT__
4201 #define __FUNCT__ "TSComputeIJacobianConstant"
4202 /*@C
4203    TSComputeIJacobianConstant - Reuses a time-independent for a semi-implicit DAE or ODE
4204 
4205    Collective on TS
4206 
4207    Input Arguments:
4208 +  ts - time stepping context
4209 .  t - time at which to evaluate
4210 .  U - state at which to evaluate
4211 .  Udot - time derivative of state vector
4212 .  shift - shift to apply
4213 -  ctx - context
4214 
4215    Output Arguments:
4216 +  A - pointer to operator
4217 .  B - pointer to preconditioning matrix
4218 -  flg - matrix structure flag
4219 
4220    Level: advanced
4221 
4222    Notes:
4223    This function is intended to be passed to TSSetIJacobian() to evaluate the Jacobian for linear time-independent problems.
4224 
4225    It is only appropriate for problems of the form
4226 
4227 $     M Udot = F(U,t)
4228 
4229   where M is constant and F is non-stiff.  The user must pass M to TSSetIJacobian().  The current implementation only
4230   works with IMEX time integration methods such as TSROSW and TSARKIMEX, since there is no support for de-constructing
4231   an implicit operator of the form
4232 
4233 $    shift*M + J
4234 
4235   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
4236   a copy of M or reassemble it when requested.
4237 
4238 .seealso: TSSetIFunction(), TSSetIJacobian(), TSComputeIFunctionLinear()
4239 @*/
4240 PetscErrorCode TSComputeIJacobianConstant(TS ts,PetscReal t,Vec U,Vec Udot,PetscReal shift,Mat A,Mat B,void *ctx)
4241 {
4242   PetscErrorCode ierr;
4243 
4244   PetscFunctionBegin;
4245   ierr = MatScale(A, shift / ts->ijacobian.shift);CHKERRQ(ierr);
4246   ts->ijacobian.shift = shift;
4247   PetscFunctionReturn(0);
4248 }
4249 
4250 #undef __FUNCT__
4251 #define __FUNCT__ "TSGetEquationType"
4252 /*@
4253    TSGetEquationType - Gets the type of the equation that TS is solving.
4254 
4255    Not Collective
4256 
4257    Input Parameter:
4258 .  ts - the TS context
4259 
4260    Output Parameter:
4261 .  equation_type - see TSEquationType
4262 
4263    Level: beginner
4264 
4265 .keywords: TS, equation type
4266 
4267 .seealso: TSSetEquationType(), TSEquationType
4268 @*/
4269 PetscErrorCode  TSGetEquationType(TS ts,TSEquationType *equation_type)
4270 {
4271   PetscFunctionBegin;
4272   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
4273   PetscValidPointer(equation_type,2);
4274   *equation_type = ts->equation_type;
4275   PetscFunctionReturn(0);
4276 }
4277 
4278 #undef __FUNCT__
4279 #define __FUNCT__ "TSSetEquationType"
4280 /*@
4281    TSSetEquationType - Sets the type of the equation that TS is solving.
4282 
4283    Not Collective
4284 
4285    Input Parameter:
4286 +  ts - the TS context
4287 .  equation_type - see TSEquationType
4288 
4289    Level: advanced
4290 
4291 .keywords: TS, equation type
4292 
4293 .seealso: TSGetEquationType(), TSEquationType
4294 @*/
4295 PetscErrorCode  TSSetEquationType(TS ts,TSEquationType equation_type)
4296 {
4297   PetscFunctionBegin;
4298   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
4299   ts->equation_type = equation_type;
4300   PetscFunctionReturn(0);
4301 }
4302 
4303 #undef __FUNCT__
4304 #define __FUNCT__ "TSGetConvergedReason"
4305 /*@
4306    TSGetConvergedReason - Gets the reason the TS iteration was stopped.
4307 
4308    Not Collective
4309 
4310    Input Parameter:
4311 .  ts - the TS context
4312 
4313    Output Parameter:
4314 .  reason - negative value indicates diverged, positive value converged, see TSConvergedReason or the
4315             manual pages for the individual convergence tests for complete lists
4316 
4317    Level: beginner
4318 
4319    Notes:
4320    Can only be called after the call to TSSolve() is complete.
4321 
4322 .keywords: TS, nonlinear, set, convergence, test
4323 
4324 .seealso: TSSetConvergenceTest(), TSConvergedReason
4325 @*/
4326 PetscErrorCode  TSGetConvergedReason(TS ts,TSConvergedReason *reason)
4327 {
4328   PetscFunctionBegin;
4329   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
4330   PetscValidPointer(reason,2);
4331   *reason = ts->reason;
4332   PetscFunctionReturn(0);
4333 }
4334 
4335 #undef __FUNCT__
4336 #define __FUNCT__ "TSSetConvergedReason"
4337 /*@
4338    TSSetConvergedReason - Sets the reason for handling the convergence of TSSolve.
4339 
4340    Not Collective
4341 
4342    Input Parameter:
4343 +  ts - the TS context
4344 .  reason - negative value indicates diverged, positive value converged, see TSConvergedReason or the
4345             manual pages for the individual convergence tests for complete lists
4346 
4347    Level: advanced
4348 
4349    Notes:
4350    Can only be called during TSSolve() is active.
4351 
4352 .keywords: TS, nonlinear, set, convergence, test
4353 
4354 .seealso: TSConvergedReason
4355 @*/
4356 PetscErrorCode  TSSetConvergedReason(TS ts,TSConvergedReason reason)
4357 {
4358   PetscFunctionBegin;
4359   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
4360   ts->reason = reason;
4361   PetscFunctionReturn(0);
4362 }
4363 
4364 #undef __FUNCT__
4365 #define __FUNCT__ "TSGetSolveTime"
4366 /*@
4367    TSGetSolveTime - Gets the time after a call to TSSolve()
4368 
4369    Not Collective
4370 
4371    Input Parameter:
4372 .  ts - the TS context
4373 
4374    Output Parameter:
4375 .  ftime - the final time. This time should correspond to the final time set with TSSetDuration()
4376 
4377    Level: beginner
4378 
4379    Notes:
4380    Can only be called after the call to TSSolve() is complete.
4381 
4382 .keywords: TS, nonlinear, set, convergence, test
4383 
4384 .seealso: TSSetConvergenceTest(), TSConvergedReason
4385 @*/
4386 PetscErrorCode  TSGetSolveTime(TS ts,PetscReal *ftime)
4387 {
4388   PetscFunctionBegin;
4389   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
4390   PetscValidPointer(ftime,2);
4391   *ftime = ts->solvetime;
4392   PetscFunctionReturn(0);
4393 }
4394 
4395 #undef __FUNCT__
4396 #define __FUNCT__ "TSGetSNESIterations"
4397 /*@
4398    TSGetSNESIterations - Gets the total number of nonlinear iterations
4399    used by the time integrator.
4400 
4401    Not Collective
4402 
4403    Input Parameter:
4404 .  ts - TS context
4405 
4406    Output Parameter:
4407 .  nits - number of nonlinear iterations
4408 
4409    Notes:
4410    This counter is reset to zero for each successive call to TSSolve().
4411 
4412    Level: intermediate
4413 
4414 .keywords: TS, get, number, nonlinear, iterations
4415 
4416 .seealso:  TSGetKSPIterations()
4417 @*/
4418 PetscErrorCode TSGetSNESIterations(TS ts,PetscInt *nits)
4419 {
4420   PetscFunctionBegin;
4421   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
4422   PetscValidIntPointer(nits,2);
4423   *nits = ts->snes_its;
4424   PetscFunctionReturn(0);
4425 }
4426 
4427 #undef __FUNCT__
4428 #define __FUNCT__ "TSGetKSPIterations"
4429 /*@
4430    TSGetKSPIterations - Gets the total number of linear iterations
4431    used by the time integrator.
4432 
4433    Not Collective
4434 
4435    Input Parameter:
4436 .  ts - TS context
4437 
4438    Output Parameter:
4439 .  lits - number of linear iterations
4440 
4441    Notes:
4442    This counter is reset to zero for each successive call to TSSolve().
4443 
4444    Level: intermediate
4445 
4446 .keywords: TS, get, number, linear, iterations
4447 
4448 .seealso:  TSGetSNESIterations(), SNESGetKSPIterations()
4449 @*/
4450 PetscErrorCode TSGetKSPIterations(TS ts,PetscInt *lits)
4451 {
4452   PetscFunctionBegin;
4453   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
4454   PetscValidIntPointer(lits,2);
4455   *lits = ts->ksp_its;
4456   PetscFunctionReturn(0);
4457 }
4458 
4459 #undef __FUNCT__
4460 #define __FUNCT__ "TSGetStepRejections"
4461 /*@
4462    TSGetStepRejections - Gets the total number of rejected steps.
4463 
4464    Not Collective
4465 
4466    Input Parameter:
4467 .  ts - TS context
4468 
4469    Output Parameter:
4470 .  rejects - number of steps rejected
4471 
4472    Notes:
4473    This counter is reset to zero for each successive call to TSSolve().
4474 
4475    Level: intermediate
4476 
4477 .keywords: TS, get, number
4478 
4479 .seealso:  TSGetSNESIterations(), TSGetKSPIterations(), TSSetMaxStepRejections(), TSGetSNESFailures(), TSSetMaxSNESFailures(), TSSetErrorIfStepFails()
4480 @*/
4481 PetscErrorCode TSGetStepRejections(TS ts,PetscInt *rejects)
4482 {
4483   PetscFunctionBegin;
4484   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
4485   PetscValidIntPointer(rejects,2);
4486   *rejects = ts->reject;
4487   PetscFunctionReturn(0);
4488 }
4489 
4490 #undef __FUNCT__
4491 #define __FUNCT__ "TSGetSNESFailures"
4492 /*@
4493    TSGetSNESFailures - Gets the total number of failed SNES solves
4494 
4495    Not Collective
4496 
4497    Input Parameter:
4498 .  ts - TS context
4499 
4500    Output Parameter:
4501 .  fails - number of failed nonlinear solves
4502 
4503    Notes:
4504    This counter is reset to zero for each successive call to TSSolve().
4505 
4506    Level: intermediate
4507 
4508 .keywords: TS, get, number
4509 
4510 .seealso:  TSGetSNESIterations(), TSGetKSPIterations(), TSSetMaxStepRejections(), TSGetStepRejections(), TSSetMaxSNESFailures()
4511 @*/
4512 PetscErrorCode TSGetSNESFailures(TS ts,PetscInt *fails)
4513 {
4514   PetscFunctionBegin;
4515   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
4516   PetscValidIntPointer(fails,2);
4517   *fails = ts->num_snes_failures;
4518   PetscFunctionReturn(0);
4519 }
4520 
4521 #undef __FUNCT__
4522 #define __FUNCT__ "TSSetMaxStepRejections"
4523 /*@
4524    TSSetMaxStepRejections - Sets the maximum number of step rejections before a step fails
4525 
4526    Not Collective
4527 
4528    Input Parameter:
4529 +  ts - TS context
4530 -  rejects - maximum number of rejected steps, pass -1 for unlimited
4531 
4532    Notes:
4533    The counter is reset to zero for each step
4534 
4535    Options Database Key:
4536  .  -ts_max_reject - Maximum number of step rejections before a step fails
4537 
4538    Level: intermediate
4539 
4540 .keywords: TS, set, maximum, number
4541 
4542 .seealso:  TSGetSNESIterations(), TSGetKSPIterations(), TSSetMaxSNESFailures(), TSGetStepRejections(), TSGetSNESFailures(), TSSetErrorIfStepFails(), TSGetConvergedReason()
4543 @*/
4544 PetscErrorCode TSSetMaxStepRejections(TS ts,PetscInt rejects)
4545 {
4546   PetscFunctionBegin;
4547   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
4548   ts->max_reject = rejects;
4549   PetscFunctionReturn(0);
4550 }
4551 
4552 #undef __FUNCT__
4553 #define __FUNCT__ "TSSetMaxSNESFailures"
4554 /*@
4555    TSSetMaxSNESFailures - Sets the maximum number of failed SNES solves
4556 
4557    Not Collective
4558 
4559    Input Parameter:
4560 +  ts - TS context
4561 -  fails - maximum number of failed nonlinear solves, pass -1 for unlimited
4562 
4563    Notes:
4564    The counter is reset to zero for each successive call to TSSolve().
4565 
4566    Options Database Key:
4567  .  -ts_max_snes_failures - Maximum number of nonlinear solve failures
4568 
4569    Level: intermediate
4570 
4571 .keywords: TS, set, maximum, number
4572 
4573 .seealso:  TSGetSNESIterations(), TSGetKSPIterations(), TSSetMaxStepRejections(), TSGetStepRejections(), TSGetSNESFailures(), SNESGetConvergedReason(), TSGetConvergedReason()
4574 @*/
4575 PetscErrorCode TSSetMaxSNESFailures(TS ts,PetscInt fails)
4576 {
4577   PetscFunctionBegin;
4578   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
4579   ts->max_snes_failures = fails;
4580   PetscFunctionReturn(0);
4581 }
4582 
4583 #undef __FUNCT__
4584 #define __FUNCT__ "TSSetErrorIfStepFails"
4585 /*@
4586    TSSetErrorIfStepFails - Error if no step succeeds
4587 
4588    Not Collective
4589 
4590    Input Parameter:
4591 +  ts - TS context
4592 -  err - PETSC_TRUE to error if no step succeeds, PETSC_FALSE to return without failure
4593 
4594    Options Database Key:
4595  .  -ts_error_if_step_fails - Error if no step succeeds
4596 
4597    Level: intermediate
4598 
4599 .keywords: TS, set, error
4600 
4601 .seealso:  TSGetSNESIterations(), TSGetKSPIterations(), TSSetMaxStepRejections(), TSGetStepRejections(), TSGetSNESFailures(), TSSetErrorIfStepFails(), TSGetConvergedReason()
4602 @*/
4603 PetscErrorCode TSSetErrorIfStepFails(TS ts,PetscBool err)
4604 {
4605   PetscFunctionBegin;
4606   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
4607   ts->errorifstepfailed = err;
4608   PetscFunctionReturn(0);
4609 }
4610 
4611 #undef __FUNCT__
4612 #define __FUNCT__ "TSMonitorSolutionBinary"
4613 /*@C
4614    TSMonitorSolutionBinary - Monitors progress of the TS solvers by VecView() for the solution at each timestep. Normally the viewer is a binary file
4615 
4616    Collective on TS
4617 
4618    Input Parameters:
4619 +  ts - the TS context
4620 .  step - current time-step
4621 .  ptime - current time
4622 .  u - current state
4623 -  viewer - binary viewer
4624 
4625    Level: intermediate
4626 
4627 .keywords: TS,  vector, monitor, view
4628 
4629 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView()
4630 @*/
4631 PetscErrorCode  TSMonitorSolutionBinary(TS ts,PetscInt step,PetscReal ptime,Vec u,void *viewer)
4632 {
4633   PetscErrorCode ierr;
4634   PetscViewer    v = (PetscViewer)viewer;
4635 
4636   PetscFunctionBegin;
4637   ierr = VecView(u,v);CHKERRQ(ierr);
4638   PetscFunctionReturn(0);
4639 }
4640 
4641 #undef __FUNCT__
4642 #define __FUNCT__ "TSMonitorSolutionVTK"
4643 /*@C
4644    TSMonitorSolutionVTK - Monitors progress of the TS solvers by VecView() for the solution at each timestep.
4645 
4646    Collective on TS
4647 
4648    Input Parameters:
4649 +  ts - the TS context
4650 .  step - current time-step
4651 .  ptime - current time
4652 .  u - current state
4653 -  filenametemplate - string containing a format specifier for the integer time step (e.g. %03D)
4654 
4655    Level: intermediate
4656 
4657    Notes:
4658    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.
4659    These are named according to the file name template.
4660 
4661    This function is normally passed as an argument to TSMonitorSet() along with TSMonitorSolutionVTKDestroy().
4662 
4663 .keywords: TS,  vector, monitor, view
4664 
4665 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView()
4666 @*/
4667 PetscErrorCode TSMonitorSolutionVTK(TS ts,PetscInt step,PetscReal ptime,Vec u,void *filenametemplate)
4668 {
4669   PetscErrorCode ierr;
4670   char           filename[PETSC_MAX_PATH_LEN];
4671   PetscViewer    viewer;
4672 
4673   PetscFunctionBegin;
4674   ierr = PetscSNPrintf(filename,sizeof(filename),(const char*)filenametemplate,step);CHKERRQ(ierr);
4675   ierr = PetscViewerVTKOpen(PetscObjectComm((PetscObject)ts),filename,FILE_MODE_WRITE,&viewer);CHKERRQ(ierr);
4676   ierr = VecView(u,viewer);CHKERRQ(ierr);
4677   ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr);
4678   PetscFunctionReturn(0);
4679 }
4680 
4681 #undef __FUNCT__
4682 #define __FUNCT__ "TSMonitorSolutionVTKDestroy"
4683 /*@C
4684    TSMonitorSolutionVTKDestroy - Destroy context for monitoring
4685 
4686    Collective on TS
4687 
4688    Input Parameters:
4689 .  filenametemplate - string containing a format specifier for the integer time step (e.g. %03D)
4690 
4691    Level: intermediate
4692 
4693    Note:
4694    This function is normally passed to TSMonitorSet() along with TSMonitorSolutionVTK().
4695 
4696 .keywords: TS,  vector, monitor, view
4697 
4698 .seealso: TSMonitorSet(), TSMonitorSolutionVTK()
4699 @*/
4700 PetscErrorCode TSMonitorSolutionVTKDestroy(void *filenametemplate)
4701 {
4702   PetscErrorCode ierr;
4703 
4704   PetscFunctionBegin;
4705   ierr = PetscFree(*(char**)filenametemplate);CHKERRQ(ierr);
4706   PetscFunctionReturn(0);
4707 }
4708 
4709 #undef __FUNCT__
4710 #define __FUNCT__ "TSGetAdapt"
4711 /*@
4712    TSGetAdapt - Get the adaptive controller context for the current method
4713 
4714    Collective on TS if controller has not been created yet
4715 
4716    Input Arguments:
4717 .  ts - time stepping context
4718 
4719    Output Arguments:
4720 .  adapt - adaptive controller
4721 
4722    Level: intermediate
4723 
4724 .seealso: TSAdapt, TSAdaptSetType(), TSAdaptChoose()
4725 @*/
4726 PetscErrorCode TSGetAdapt(TS ts,TSAdapt *adapt)
4727 {
4728   PetscErrorCode ierr;
4729 
4730   PetscFunctionBegin;
4731   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
4732   PetscValidPointer(adapt,2);
4733   if (!ts->adapt) {
4734     ierr = TSAdaptCreate(PetscObjectComm((PetscObject)ts),&ts->adapt);CHKERRQ(ierr);
4735     ierr = PetscLogObjectParent((PetscObject)ts,(PetscObject)ts->adapt);CHKERRQ(ierr);
4736     ierr = PetscObjectIncrementTabLevel((PetscObject)ts->adapt,(PetscObject)ts,1);CHKERRQ(ierr);
4737   }
4738   *adapt = ts->adapt;
4739   PetscFunctionReturn(0);
4740 }
4741 
4742 #undef __FUNCT__
4743 #define __FUNCT__ "TSSetTolerances"
4744 /*@
4745    TSSetTolerances - Set tolerances for local truncation error when using adaptive controller
4746 
4747    Logically Collective
4748 
4749    Input Arguments:
4750 +  ts - time integration context
4751 .  atol - scalar absolute tolerances, PETSC_DECIDE to leave current value
4752 .  vatol - vector of absolute tolerances or NULL, used in preference to atol if present
4753 .  rtol - scalar relative tolerances, PETSC_DECIDE to leave current value
4754 -  vrtol - vector of relative tolerances or NULL, used in preference to atol if present
4755 
4756    Options Database keys:
4757 +  -ts_rtol <rtol> - relative tolerance for local truncation error
4758 -  -ts_atol <atol> Absolute tolerance for local truncation error
4759 
4760    Level: beginner
4761 
4762 .seealso: TS, TSAdapt, TSVecNormWRMS(), TSGetTolerances()
4763 @*/
4764 PetscErrorCode TSSetTolerances(TS ts,PetscReal atol,Vec vatol,PetscReal rtol,Vec vrtol)
4765 {
4766   PetscErrorCode ierr;
4767 
4768   PetscFunctionBegin;
4769   if (atol != PETSC_DECIDE && atol != PETSC_DEFAULT) ts->atol = atol;
4770   if (vatol) {
4771     ierr = PetscObjectReference((PetscObject)vatol);CHKERRQ(ierr);
4772     ierr = VecDestroy(&ts->vatol);CHKERRQ(ierr);
4773 
4774     ts->vatol = vatol;
4775   }
4776   if (rtol != PETSC_DECIDE && rtol != PETSC_DEFAULT) ts->rtol = rtol;
4777   if (vrtol) {
4778     ierr = PetscObjectReference((PetscObject)vrtol);CHKERRQ(ierr);
4779     ierr = VecDestroy(&ts->vrtol);CHKERRQ(ierr);
4780 
4781     ts->vrtol = vrtol;
4782   }
4783   PetscFunctionReturn(0);
4784 }
4785 
4786 #undef __FUNCT__
4787 #define __FUNCT__ "TSGetTolerances"
4788 /*@
4789    TSGetTolerances - Get tolerances for local truncation error when using adaptive controller
4790 
4791    Logically Collective
4792 
4793    Input Arguments:
4794 .  ts - time integration context
4795 
4796    Output Arguments:
4797 +  atol - scalar absolute tolerances, NULL to ignore
4798 .  vatol - vector of absolute tolerances, NULL to ignore
4799 .  rtol - scalar relative tolerances, NULL to ignore
4800 -  vrtol - vector of relative tolerances, NULL to ignore
4801 
4802    Level: beginner
4803 
4804 .seealso: TS, TSAdapt, TSVecNormWRMS(), TSSetTolerances()
4805 @*/
4806 PetscErrorCode TSGetTolerances(TS ts,PetscReal *atol,Vec *vatol,PetscReal *rtol,Vec *vrtol)
4807 {
4808   PetscFunctionBegin;
4809   if (atol)  *atol  = ts->atol;
4810   if (vatol) *vatol = ts->vatol;
4811   if (rtol)  *rtol  = ts->rtol;
4812   if (vrtol) *vrtol = ts->vrtol;
4813   PetscFunctionReturn(0);
4814 }
4815 
4816 #undef __FUNCT__
4817 #define __FUNCT__ "TSErrorNormWRMS"
4818 /*@
4819    TSErrorNormWRMS - compute a weighted norm of the difference between a vector and the current state
4820 
4821    Collective on TS
4822 
4823    Input Arguments:
4824 +  ts - time stepping context
4825 -  Y - state vector to be compared to ts->vec_sol
4826 
4827    Output Arguments:
4828 .  norm - weighted norm, a value of 1.0 is considered small
4829 
4830    Level: developer
4831 
4832 .seealso: TSSetTolerances()
4833 @*/
4834 PetscErrorCode TSErrorNormWRMS(TS ts,Vec Y,PetscReal *norm)
4835 {
4836   PetscErrorCode    ierr;
4837   PetscInt          i,n,N;
4838   const PetscScalar *u,*y;
4839   Vec               U;
4840   PetscReal         sum,gsum;
4841 
4842   PetscFunctionBegin;
4843   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
4844   PetscValidHeaderSpecific(Y,VEC_CLASSID,2);
4845   PetscValidPointer(norm,3);
4846   U = ts->vec_sol;
4847   PetscCheckSameTypeAndComm(U,1,Y,2);
4848   if (U == Y) SETERRQ(PetscObjectComm((PetscObject)U),PETSC_ERR_ARG_IDN,"Y cannot be the TS solution vector");
4849 
4850   ierr = VecGetSize(U,&N);CHKERRQ(ierr);
4851   ierr = VecGetLocalSize(U,&n);CHKERRQ(ierr);
4852   ierr = VecGetArrayRead(U,&u);CHKERRQ(ierr);
4853   ierr = VecGetArrayRead(Y,&y);CHKERRQ(ierr);
4854   sum  = 0.;
4855   if (ts->vatol && ts->vrtol) {
4856     const PetscScalar *atol,*rtol;
4857     ierr = VecGetArrayRead(ts->vatol,&atol);CHKERRQ(ierr);
4858     ierr = VecGetArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr);
4859     for (i=0; i<n; i++) {
4860       PetscReal tol = PetscRealPart(atol[i]) + PetscRealPart(rtol[i]) * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i]));
4861       sum += PetscSqr(PetscAbsScalar(y[i] - u[i]) / tol);
4862     }
4863     ierr = VecRestoreArrayRead(ts->vatol,&atol);CHKERRQ(ierr);
4864     ierr = VecRestoreArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr);
4865   } else if (ts->vatol) {       /* vector atol, scalar rtol */
4866     const PetscScalar *atol;
4867     ierr = VecGetArrayRead(ts->vatol,&atol);CHKERRQ(ierr);
4868     for (i=0; i<n; i++) {
4869       PetscReal tol = PetscRealPart(atol[i]) + ts->rtol * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i]));
4870       sum += PetscSqr(PetscAbsScalar(y[i] - u[i]) / tol);
4871     }
4872     ierr = VecRestoreArrayRead(ts->vatol,&atol);CHKERRQ(ierr);
4873   } else if (ts->vrtol) {       /* scalar atol, vector rtol */
4874     const PetscScalar *rtol;
4875     ierr = VecGetArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr);
4876     for (i=0; i<n; i++) {
4877       PetscReal tol = ts->atol + PetscRealPart(rtol[i]) * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i]));
4878       sum += PetscSqr(PetscAbsScalar(y[i] - u[i]) / tol);
4879     }
4880     ierr = VecRestoreArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr);
4881   } else {                      /* scalar atol, scalar rtol */
4882     for (i=0; i<n; i++) {
4883       PetscReal tol = ts->atol + ts->rtol * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i]));
4884       sum += PetscSqr(PetscAbsScalar(y[i] - u[i]) / tol);
4885     }
4886   }
4887   ierr = VecRestoreArrayRead(U,&u);CHKERRQ(ierr);
4888   ierr = VecRestoreArrayRead(Y,&y);CHKERRQ(ierr);
4889 
4890   ierr  = MPI_Allreduce(&sum,&gsum,1,MPIU_REAL,MPIU_SUM,PetscObjectComm((PetscObject)ts));CHKERRQ(ierr);
4891   *norm = PetscSqrtReal(gsum / N);
4892   if (PetscIsInfOrNanReal(*norm)) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_FP,"Infinite or not-a-number generated in norm");
4893   PetscFunctionReturn(0);
4894 }
4895 
4896 #undef __FUNCT__
4897 #define __FUNCT__ "TSSetCFLTimeLocal"
4898 /*@
4899    TSSetCFLTimeLocal - Set the local CFL constraint relative to forward Euler
4900 
4901    Logically Collective on TS
4902 
4903    Input Arguments:
4904 +  ts - time stepping context
4905 -  cfltime - maximum stable time step if using forward Euler (value can be different on each process)
4906 
4907    Note:
4908    After calling this function, the global CFL time can be obtained by calling TSGetCFLTime()
4909 
4910    Level: intermediate
4911 
4912 .seealso: TSGetCFLTime(), TSADAPTCFL
4913 @*/
4914 PetscErrorCode TSSetCFLTimeLocal(TS ts,PetscReal cfltime)
4915 {
4916   PetscFunctionBegin;
4917   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
4918   ts->cfltime_local = cfltime;
4919   ts->cfltime       = -1.;
4920   PetscFunctionReturn(0);
4921 }
4922 
4923 #undef __FUNCT__
4924 #define __FUNCT__ "TSGetCFLTime"
4925 /*@
4926    TSGetCFLTime - Get the maximum stable time step according to CFL criteria applied to forward Euler
4927 
4928    Collective on TS
4929 
4930    Input Arguments:
4931 .  ts - time stepping context
4932 
4933    Output Arguments:
4934 .  cfltime - maximum stable time step for forward Euler
4935 
4936    Level: advanced
4937 
4938 .seealso: TSSetCFLTimeLocal()
4939 @*/
4940 PetscErrorCode TSGetCFLTime(TS ts,PetscReal *cfltime)
4941 {
4942   PetscErrorCode ierr;
4943 
4944   PetscFunctionBegin;
4945   if (ts->cfltime < 0) {
4946     ierr = MPI_Allreduce(&ts->cfltime_local,&ts->cfltime,1,MPIU_REAL,MPIU_MIN,PetscObjectComm((PetscObject)ts));CHKERRQ(ierr);
4947   }
4948   *cfltime = ts->cfltime;
4949   PetscFunctionReturn(0);
4950 }
4951 
4952 #undef __FUNCT__
4953 #define __FUNCT__ "TSVISetVariableBounds"
4954 /*@
4955    TSVISetVariableBounds - Sets the lower and upper bounds for the solution vector. xl <= x <= xu
4956 
4957    Input Parameters:
4958 .  ts   - the TS context.
4959 .  xl   - lower bound.
4960 .  xu   - upper bound.
4961 
4962    Notes:
4963    If this routine is not called then the lower and upper bounds are set to
4964    PETSC_NINFINITY and PETSC_INFINITY respectively during SNESSetUp().
4965 
4966    Level: advanced
4967 
4968 @*/
4969 PetscErrorCode TSVISetVariableBounds(TS ts, Vec xl, Vec xu)
4970 {
4971   PetscErrorCode ierr;
4972   SNES           snes;
4973 
4974   PetscFunctionBegin;
4975   ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr);
4976   ierr = SNESVISetVariableBounds(snes,xl,xu);CHKERRQ(ierr);
4977   PetscFunctionReturn(0);
4978 }
4979 
4980 #if defined(PETSC_HAVE_MATLAB_ENGINE)
4981 #include <mex.h>
4982 
4983 typedef struct {char *funcname; mxArray *ctx;} TSMatlabContext;
4984 
4985 #undef __FUNCT__
4986 #define __FUNCT__ "TSComputeFunction_Matlab"
4987 /*
4988    TSComputeFunction_Matlab - Calls the function that has been set with
4989                          TSSetFunctionMatlab().
4990 
4991    Collective on TS
4992 
4993    Input Parameters:
4994 +  snes - the TS context
4995 -  u - input vector
4996 
4997    Output Parameter:
4998 .  y - function vector, as set by TSSetFunction()
4999 
5000    Notes:
5001    TSComputeFunction() is typically used within nonlinear solvers
5002    implementations, so most users would not generally call this routine
5003    themselves.
5004 
5005    Level: developer
5006 
5007 .keywords: TS, nonlinear, compute, function
5008 
5009 .seealso: TSSetFunction(), TSGetFunction()
5010 */
5011 PetscErrorCode  TSComputeFunction_Matlab(TS snes,PetscReal time,Vec u,Vec udot,Vec y, void *ctx)
5012 {
5013   PetscErrorCode  ierr;
5014   TSMatlabContext *sctx = (TSMatlabContext*)ctx;
5015   int             nlhs  = 1,nrhs = 7;
5016   mxArray         *plhs[1],*prhs[7];
5017   long long int   lx = 0,lxdot = 0,ly = 0,ls = 0;
5018 
5019   PetscFunctionBegin;
5020   PetscValidHeaderSpecific(snes,TS_CLASSID,1);
5021   PetscValidHeaderSpecific(u,VEC_CLASSID,3);
5022   PetscValidHeaderSpecific(udot,VEC_CLASSID,4);
5023   PetscValidHeaderSpecific(y,VEC_CLASSID,5);
5024   PetscCheckSameComm(snes,1,u,3);
5025   PetscCheckSameComm(snes,1,y,5);
5026 
5027   ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr);
5028   ierr = PetscMemcpy(&lx,&u,sizeof(u));CHKERRQ(ierr);
5029   ierr = PetscMemcpy(&lxdot,&udot,sizeof(udot));CHKERRQ(ierr);
5030   ierr = PetscMemcpy(&ly,&y,sizeof(u));CHKERRQ(ierr);
5031 
5032   prhs[0] =  mxCreateDoubleScalar((double)ls);
5033   prhs[1] =  mxCreateDoubleScalar(time);
5034   prhs[2] =  mxCreateDoubleScalar((double)lx);
5035   prhs[3] =  mxCreateDoubleScalar((double)lxdot);
5036   prhs[4] =  mxCreateDoubleScalar((double)ly);
5037   prhs[5] =  mxCreateString(sctx->funcname);
5038   prhs[6] =  sctx->ctx;
5039   ierr    =  mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscTSComputeFunctionInternal");CHKERRQ(ierr);
5040   ierr    =  mxGetScalar(plhs[0]);CHKERRQ(ierr);
5041   mxDestroyArray(prhs[0]);
5042   mxDestroyArray(prhs[1]);
5043   mxDestroyArray(prhs[2]);
5044   mxDestroyArray(prhs[3]);
5045   mxDestroyArray(prhs[4]);
5046   mxDestroyArray(prhs[5]);
5047   mxDestroyArray(plhs[0]);
5048   PetscFunctionReturn(0);
5049 }
5050 
5051 
5052 #undef __FUNCT__
5053 #define __FUNCT__ "TSSetFunctionMatlab"
5054 /*
5055    TSSetFunctionMatlab - Sets the function evaluation routine and function
5056    vector for use by the TS routines in solving ODEs
5057    equations from MATLAB. Here the function is a string containing the name of a MATLAB function
5058 
5059    Logically Collective on TS
5060 
5061    Input Parameters:
5062 +  ts - the TS context
5063 -  func - function evaluation routine
5064 
5065    Calling sequence of func:
5066 $    func (TS ts,PetscReal time,Vec u,Vec udot,Vec f,void *ctx);
5067 
5068    Level: beginner
5069 
5070 .keywords: TS, nonlinear, set, function
5071 
5072 .seealso: TSGetFunction(), TSComputeFunction(), TSSetJacobian(), TSSetFunction()
5073 */
5074 PetscErrorCode  TSSetFunctionMatlab(TS ts,const char *func,mxArray *ctx)
5075 {
5076   PetscErrorCode  ierr;
5077   TSMatlabContext *sctx;
5078 
5079   PetscFunctionBegin;
5080   /* currently sctx is memory bleed */
5081   ierr = PetscMalloc(sizeof(TSMatlabContext),&sctx);CHKERRQ(ierr);
5082   ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr);
5083   /*
5084      This should work, but it doesn't
5085   sctx->ctx = ctx;
5086   mexMakeArrayPersistent(sctx->ctx);
5087   */
5088   sctx->ctx = mxDuplicateArray(ctx);
5089 
5090   ierr = TSSetIFunction(ts,NULL,TSComputeFunction_Matlab,sctx);CHKERRQ(ierr);
5091   PetscFunctionReturn(0);
5092 }
5093 
5094 #undef __FUNCT__
5095 #define __FUNCT__ "TSComputeJacobian_Matlab"
5096 /*
5097    TSComputeJacobian_Matlab - Calls the function that has been set with
5098                          TSSetJacobianMatlab().
5099 
5100    Collective on TS
5101 
5102    Input Parameters:
5103 +  ts - the TS context
5104 .  u - input vector
5105 .  A, B - the matrices
5106 -  ctx - user context
5107 
5108    Level: developer
5109 
5110 .keywords: TS, nonlinear, compute, function
5111 
5112 .seealso: TSSetFunction(), TSGetFunction()
5113 @*/
5114 PetscErrorCode  TSComputeJacobian_Matlab(TS ts,PetscReal time,Vec u,Vec udot,PetscReal shift,Mat A,Mat B,void *ctx)
5115 {
5116   PetscErrorCode  ierr;
5117   TSMatlabContext *sctx = (TSMatlabContext*)ctx;
5118   int             nlhs  = 2,nrhs = 9;
5119   mxArray         *plhs[2],*prhs[9];
5120   long long int   lx = 0,lxdot = 0,lA = 0,ls = 0, lB = 0;
5121 
5122   PetscFunctionBegin;
5123   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
5124   PetscValidHeaderSpecific(u,VEC_CLASSID,3);
5125 
5126   /* call Matlab function in ctx with arguments u and y */
5127 
5128   ierr = PetscMemcpy(&ls,&ts,sizeof(ts));CHKERRQ(ierr);
5129   ierr = PetscMemcpy(&lx,&u,sizeof(u));CHKERRQ(ierr);
5130   ierr = PetscMemcpy(&lxdot,&udot,sizeof(u));CHKERRQ(ierr);
5131   ierr = PetscMemcpy(&lA,A,sizeof(u));CHKERRQ(ierr);
5132   ierr = PetscMemcpy(&lB,B,sizeof(u));CHKERRQ(ierr);
5133 
5134   prhs[0] =  mxCreateDoubleScalar((double)ls);
5135   prhs[1] =  mxCreateDoubleScalar((double)time);
5136   prhs[2] =  mxCreateDoubleScalar((double)lx);
5137   prhs[3] =  mxCreateDoubleScalar((double)lxdot);
5138   prhs[4] =  mxCreateDoubleScalar((double)shift);
5139   prhs[5] =  mxCreateDoubleScalar((double)lA);
5140   prhs[6] =  mxCreateDoubleScalar((double)lB);
5141   prhs[7] =  mxCreateString(sctx->funcname);
5142   prhs[8] =  sctx->ctx;
5143   ierr    =  mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscTSComputeJacobianInternal");CHKERRQ(ierr);
5144   ierr    =  mxGetScalar(plhs[0]);CHKERRQ(ierr);
5145   mxDestroyArray(prhs[0]);
5146   mxDestroyArray(prhs[1]);
5147   mxDestroyArray(prhs[2]);
5148   mxDestroyArray(prhs[3]);
5149   mxDestroyArray(prhs[4]);
5150   mxDestroyArray(prhs[5]);
5151   mxDestroyArray(prhs[6]);
5152   mxDestroyArray(prhs[7]);
5153   mxDestroyArray(plhs[0]);
5154   mxDestroyArray(plhs[1]);
5155   PetscFunctionReturn(0);
5156 }
5157 
5158 
5159 #undef __FUNCT__
5160 #define __FUNCT__ "TSSetJacobianMatlab"
5161 /*
5162    TSSetJacobianMatlab - Sets the Jacobian function evaluation routine and two empty Jacobian matrices
5163    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
5164 
5165    Logically Collective on TS
5166 
5167    Input Parameters:
5168 +  ts - the TS context
5169 .  A,B - Jacobian matrices
5170 .  func - function evaluation routine
5171 -  ctx - user context
5172 
5173    Calling sequence of func:
5174 $    flag = func (TS ts,PetscReal time,Vec u,Vec udot,Mat A,Mat B,void *ctx);
5175 
5176 
5177    Level: developer
5178 
5179 .keywords: TS, nonlinear, set, function
5180 
5181 .seealso: TSGetFunction(), TSComputeFunction(), TSSetJacobian(), TSSetFunction()
5182 */
5183 PetscErrorCode  TSSetJacobianMatlab(TS ts,Mat A,Mat B,const char *func,mxArray *ctx)
5184 {
5185   PetscErrorCode  ierr;
5186   TSMatlabContext *sctx;
5187 
5188   PetscFunctionBegin;
5189   /* currently sctx is memory bleed */
5190   ierr = PetscMalloc(sizeof(TSMatlabContext),&sctx);CHKERRQ(ierr);
5191   ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr);
5192   /*
5193      This should work, but it doesn't
5194   sctx->ctx = ctx;
5195   mexMakeArrayPersistent(sctx->ctx);
5196   */
5197   sctx->ctx = mxDuplicateArray(ctx);
5198 
5199   ierr = TSSetIJacobian(ts,A,B,TSComputeJacobian_Matlab,sctx);CHKERRQ(ierr);
5200   PetscFunctionReturn(0);
5201 }
5202 
5203 #undef __FUNCT__
5204 #define __FUNCT__ "TSMonitor_Matlab"
5205 /*
5206    TSMonitor_Matlab - Calls the function that has been set with TSMonitorSetMatlab().
5207 
5208    Collective on TS
5209 
5210 .seealso: TSSetFunction(), TSGetFunction()
5211 @*/
5212 PetscErrorCode  TSMonitor_Matlab(TS ts,PetscInt it, PetscReal time,Vec u, void *ctx)
5213 {
5214   PetscErrorCode  ierr;
5215   TSMatlabContext *sctx = (TSMatlabContext*)ctx;
5216   int             nlhs  = 1,nrhs = 6;
5217   mxArray         *plhs[1],*prhs[6];
5218   long long int   lx = 0,ls = 0;
5219 
5220   PetscFunctionBegin;
5221   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
5222   PetscValidHeaderSpecific(u,VEC_CLASSID,4);
5223 
5224   ierr = PetscMemcpy(&ls,&ts,sizeof(ts));CHKERRQ(ierr);
5225   ierr = PetscMemcpy(&lx,&u,sizeof(u));CHKERRQ(ierr);
5226 
5227   prhs[0] =  mxCreateDoubleScalar((double)ls);
5228   prhs[1] =  mxCreateDoubleScalar((double)it);
5229   prhs[2] =  mxCreateDoubleScalar((double)time);
5230   prhs[3] =  mxCreateDoubleScalar((double)lx);
5231   prhs[4] =  mxCreateString(sctx->funcname);
5232   prhs[5] =  sctx->ctx;
5233   ierr    =  mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscTSMonitorInternal");CHKERRQ(ierr);
5234   ierr    =  mxGetScalar(plhs[0]);CHKERRQ(ierr);
5235   mxDestroyArray(prhs[0]);
5236   mxDestroyArray(prhs[1]);
5237   mxDestroyArray(prhs[2]);
5238   mxDestroyArray(prhs[3]);
5239   mxDestroyArray(prhs[4]);
5240   mxDestroyArray(plhs[0]);
5241   PetscFunctionReturn(0);
5242 }
5243 
5244 
5245 #undef __FUNCT__
5246 #define __FUNCT__ "TSMonitorSetMatlab"
5247 /*
5248    TSMonitorSetMatlab - Sets the monitor function from Matlab
5249 
5250    Level: developer
5251 
5252 .keywords: TS, nonlinear, set, function
5253 
5254 .seealso: TSGetFunction(), TSComputeFunction(), TSSetJacobian(), TSSetFunction()
5255 */
5256 PetscErrorCode  TSMonitorSetMatlab(TS ts,const char *func,mxArray *ctx)
5257 {
5258   PetscErrorCode  ierr;
5259   TSMatlabContext *sctx;
5260 
5261   PetscFunctionBegin;
5262   /* currently sctx is memory bleed */
5263   ierr = PetscMalloc(sizeof(TSMatlabContext),&sctx);CHKERRQ(ierr);
5264   ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr);
5265   /*
5266      This should work, but it doesn't
5267   sctx->ctx = ctx;
5268   mexMakeArrayPersistent(sctx->ctx);
5269   */
5270   sctx->ctx = mxDuplicateArray(ctx);
5271 
5272   ierr = TSMonitorSet(ts,TSMonitor_Matlab,sctx,NULL);CHKERRQ(ierr);
5273   PetscFunctionReturn(0);
5274 }
5275 #endif
5276 
5277 
5278 
5279 #undef __FUNCT__
5280 #define __FUNCT__ "TSMonitorLGSolution"
5281 /*@C
5282    TSMonitorLGSolution - Monitors progress of the TS solvers by plotting each component of the solution vector
5283        in a time based line graph
5284 
5285    Collective on TS
5286 
5287    Input Parameters:
5288 +  ts - the TS context
5289 .  step - current time-step
5290 .  ptime - current time
5291 -  lg - a line graph object
5292 
5293    Level: intermediate
5294 
5295     Notes: each process in a parallel run displays its component solutions in a separate window
5296 
5297 .keywords: TS,  vector, monitor, view
5298 
5299 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView()
5300 @*/
5301 PetscErrorCode  TSMonitorLGSolution(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dummy)
5302 {
5303   PetscErrorCode    ierr;
5304   TSMonitorLGCtx    ctx = (TSMonitorLGCtx)dummy;
5305   const PetscScalar *yy;
5306   PetscInt          dim;
5307 
5308   PetscFunctionBegin;
5309   if (!step) {
5310     PetscDrawAxis axis;
5311     ierr = PetscDrawLGGetAxis(ctx->lg,&axis);CHKERRQ(ierr);
5312     ierr = PetscDrawAxisSetLabels(axis,"Solution as function of time","Time","Solution");CHKERRQ(ierr);
5313     ierr = VecGetLocalSize(u,&dim);CHKERRQ(ierr);
5314     ierr = PetscDrawLGSetDimension(ctx->lg,dim);CHKERRQ(ierr);
5315     ierr = PetscDrawLGReset(ctx->lg);CHKERRQ(ierr);
5316   }
5317   ierr = VecGetArrayRead(u,&yy);CHKERRQ(ierr);
5318 #if defined(PETSC_USE_COMPLEX)
5319   {
5320     PetscReal *yreal;
5321     PetscInt  i,n;
5322     ierr = VecGetLocalSize(u,&n);CHKERRQ(ierr);
5323     ierr = PetscMalloc1(n,&yreal);CHKERRQ(ierr);
5324     for (i=0; i<n; i++) yreal[i] = PetscRealPart(yy[i]);
5325     ierr = PetscDrawLGAddCommonPoint(ctx->lg,ptime,yreal);CHKERRQ(ierr);
5326     ierr = PetscFree(yreal);CHKERRQ(ierr);
5327   }
5328 #else
5329   ierr = PetscDrawLGAddCommonPoint(ctx->lg,ptime,yy);CHKERRQ(ierr);
5330 #endif
5331   ierr = VecRestoreArrayRead(u,&yy);CHKERRQ(ierr);
5332   if (((ctx->howoften > 0) && (!(step % ctx->howoften))) || ((ctx->howoften == -1) && ts->reason)) {
5333     ierr = PetscDrawLGDraw(ctx->lg);CHKERRQ(ierr);
5334   }
5335   PetscFunctionReturn(0);
5336 }
5337 
5338 #undef __FUNCT__
5339 #define __FUNCT__ "TSMonitorLGError"
5340 /*@C
5341    TSMonitorLGError - Monitors progress of the TS solvers by plotting each component of the solution vector
5342        in a time based line graph
5343 
5344    Collective on TS
5345 
5346    Input Parameters:
5347 +  ts - the TS context
5348 .  step - current time-step
5349 .  ptime - current time
5350 -  lg - a line graph object
5351 
5352    Level: intermediate
5353 
5354    Notes:
5355    Only for sequential solves.
5356 
5357    The user must provide the solution using TSSetSolutionFunction() to use this monitor.
5358 
5359    Options Database Keys:
5360 .  -ts_monitor_lg_error - create a graphical monitor of error history
5361 
5362 .keywords: TS,  vector, monitor, view
5363 
5364 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSSetSolutionFunction()
5365 @*/
5366 PetscErrorCode  TSMonitorLGError(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dummy)
5367 {
5368   PetscErrorCode    ierr;
5369   TSMonitorLGCtx    ctx = (TSMonitorLGCtx)dummy;
5370   const PetscScalar *yy;
5371   Vec               y;
5372   PetscInt          dim;
5373 
5374   PetscFunctionBegin;
5375   if (!step) {
5376     PetscDrawAxis axis;
5377     ierr = PetscDrawLGGetAxis(ctx->lg,&axis);CHKERRQ(ierr);
5378     ierr = PetscDrawAxisSetLabels(axis,"Error in solution as function of time","Time","Solution");CHKERRQ(ierr);
5379     ierr = VecGetLocalSize(u,&dim);CHKERRQ(ierr);
5380     ierr = PetscDrawLGSetDimension(ctx->lg,dim);CHKERRQ(ierr);
5381     ierr = PetscDrawLGReset(ctx->lg);CHKERRQ(ierr);
5382   }
5383   ierr = VecDuplicate(u,&y);CHKERRQ(ierr);
5384   ierr = TSComputeSolutionFunction(ts,ptime,y);CHKERRQ(ierr);
5385   ierr = VecAXPY(y,-1.0,u);CHKERRQ(ierr);
5386   ierr = VecGetArrayRead(y,&yy);CHKERRQ(ierr);
5387 #if defined(PETSC_USE_COMPLEX)
5388   {
5389     PetscReal *yreal;
5390     PetscInt  i,n;
5391     ierr = VecGetLocalSize(y,&n);CHKERRQ(ierr);
5392     ierr = PetscMalloc1(n,&yreal);CHKERRQ(ierr);
5393     for (i=0; i<n; i++) yreal[i] = PetscRealPart(yy[i]);
5394     ierr = PetscDrawLGAddCommonPoint(ctx->lg,ptime,yreal);CHKERRQ(ierr);
5395     ierr = PetscFree(yreal);CHKERRQ(ierr);
5396   }
5397 #else
5398   ierr = PetscDrawLGAddCommonPoint(ctx->lg,ptime,yy);CHKERRQ(ierr);
5399 #endif
5400   ierr = VecRestoreArrayRead(y,&yy);CHKERRQ(ierr);
5401   ierr = VecDestroy(&y);CHKERRQ(ierr);
5402   if (((ctx->howoften > 0) && (!(step % ctx->howoften))) || ((ctx->howoften == -1) && ts->reason)) {
5403     ierr = PetscDrawLGDraw(ctx->lg);CHKERRQ(ierr);
5404   }
5405   PetscFunctionReturn(0);
5406 }
5407 
5408 #undef __FUNCT__
5409 #define __FUNCT__ "TSMonitorLGSNESIterations"
5410 PetscErrorCode TSMonitorLGSNESIterations(TS ts,PetscInt n,PetscReal ptime,Vec v,void *monctx)
5411 {
5412   TSMonitorLGCtx ctx = (TSMonitorLGCtx) monctx;
5413   PetscReal      x   = ptime,y;
5414   PetscErrorCode ierr;
5415   PetscInt       its;
5416 
5417   PetscFunctionBegin;
5418   if (!n) {
5419     PetscDrawAxis axis;
5420 
5421     ierr = PetscDrawLGGetAxis(ctx->lg,&axis);CHKERRQ(ierr);
5422     ierr = PetscDrawAxisSetLabels(axis,"Nonlinear iterations as function of time","Time","SNES Iterations");CHKERRQ(ierr);
5423     ierr = PetscDrawLGReset(ctx->lg);CHKERRQ(ierr);
5424 
5425     ctx->snes_its = 0;
5426   }
5427   ierr = TSGetSNESIterations(ts,&its);CHKERRQ(ierr);
5428   y    = its - ctx->snes_its;
5429   ierr = PetscDrawLGAddPoint(ctx->lg,&x,&y);CHKERRQ(ierr);
5430   if (((ctx->howoften > 0) && (!(n % ctx->howoften)) && (n > -1)) || ((ctx->howoften == -1) && (n == -1))) {
5431     ierr = PetscDrawLGDraw(ctx->lg);CHKERRQ(ierr);
5432   }
5433   ctx->snes_its = its;
5434   PetscFunctionReturn(0);
5435 }
5436 
5437 #undef __FUNCT__
5438 #define __FUNCT__ "TSMonitorLGKSPIterations"
5439 PetscErrorCode TSMonitorLGKSPIterations(TS ts,PetscInt n,PetscReal ptime,Vec v,void *monctx)
5440 {
5441   TSMonitorLGCtx ctx = (TSMonitorLGCtx) monctx;
5442   PetscReal      x   = ptime,y;
5443   PetscErrorCode ierr;
5444   PetscInt       its;
5445 
5446   PetscFunctionBegin;
5447   if (!n) {
5448     PetscDrawAxis axis;
5449 
5450     ierr = PetscDrawLGGetAxis(ctx->lg,&axis);CHKERRQ(ierr);
5451     ierr = PetscDrawAxisSetLabels(axis,"Linear iterations as function of time","Time","KSP Iterations");CHKERRQ(ierr);
5452     ierr = PetscDrawLGReset(ctx->lg);CHKERRQ(ierr);
5453 
5454     ctx->ksp_its = 0;
5455   }
5456   ierr = TSGetKSPIterations(ts,&its);CHKERRQ(ierr);
5457   y    = its - ctx->ksp_its;
5458   ierr = PetscDrawLGAddPoint(ctx->lg,&x,&y);CHKERRQ(ierr);
5459   if (((ctx->howoften > 0) && (!(n % ctx->howoften)) && (n > -1)) || ((ctx->howoften == -1) && (n == -1))) {
5460     ierr = PetscDrawLGDraw(ctx->lg);CHKERRQ(ierr);
5461   }
5462   ctx->ksp_its = its;
5463   PetscFunctionReturn(0);
5464 }
5465 
5466 #undef __FUNCT__
5467 #define __FUNCT__ "TSComputeLinearStability"
5468 /*@
5469    TSComputeLinearStability - computes the linear stability function at a point
5470 
5471    Collective on TS and Vec
5472 
5473    Input Parameters:
5474 +  ts - the TS context
5475 -  xr,xi - real and imaginary part of input arguments
5476 
5477    Output Parameters:
5478 .  yr,yi - real and imaginary part of function value
5479 
5480    Level: developer
5481 
5482 .keywords: TS, compute
5483 
5484 .seealso: TSSetRHSFunction(), TSComputeIFunction()
5485 @*/
5486 PetscErrorCode TSComputeLinearStability(TS ts,PetscReal xr,PetscReal xi,PetscReal *yr,PetscReal *yi)
5487 {
5488   PetscErrorCode ierr;
5489 
5490   PetscFunctionBegin;
5491   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
5492   if (!ts->ops->linearstability) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"Linearized stability function not provided for this method");
5493   ierr = (*ts->ops->linearstability)(ts,xr,xi,yr,yi);CHKERRQ(ierr);
5494   PetscFunctionReturn(0);
5495 }
5496 
5497 #undef __FUNCT__
5498 #define __FUNCT__ "TSRollBack"
5499 /*@
5500    TSRollBack - Rolls back one time step
5501 
5502    Collective on TS
5503 
5504    Input Parameter:
5505 .  ts - the TS context obtained from TSCreate()
5506 
5507    Level: advanced
5508 
5509 .keywords: TS, timestep, rollback
5510 
5511 .seealso: TSCreate(), TSSetUp(), TSDestroy(), TSSolve(), TSSetPreStep(), TSSetPreStage(), TSInterpolate()
5512 @*/
5513 PetscErrorCode  TSRollBack(TS ts)
5514 {
5515   PetscErrorCode ierr;
5516 
5517   PetscFunctionBegin;
5518   PetscValidHeaderSpecific(ts, TS_CLASSID,1);
5519 
5520   if (!ts->ops->rollback) SETERRQ1(PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"TSRollBack not implemented for type '%s'",((PetscObject)ts)->type_name);
5521   ierr = (*ts->ops->rollback)(ts);CHKERRQ(ierr);
5522   ts->time_step = ts->ptime - ts->ptime_prev;
5523   ts->ptime = ts->ptime_prev;
5524   PetscFunctionReturn(0);
5525 }
5526 
5527 #undef __FUNCT__
5528 #define __FUNCT__ "TSGetStages"
5529 /*@
5530    TSGetStages - Get the number of stages and stage values
5531 
5532    Input Parameter:
5533 .  ts - the TS context obtained from TSCreate()
5534 
5535    Level: advanced
5536 
5537 .keywords: TS, getstages
5538 
5539 .seealso: TSCreate()
5540 @*/
5541 PetscErrorCode  TSGetStages(TS ts,PetscInt *ns, Vec **Y)
5542 {
5543   PetscErrorCode ierr;
5544 
5545   PetscFunctionBegin;
5546   PetscValidHeaderSpecific(ts, TS_CLASSID,1);
5547   PetscValidPointer(ns,2);
5548 
5549   if (!ts->ops->getstages) *ns=0;
5550   else {
5551     ierr = (*ts->ops->getstages)(ts,ns,Y);CHKERRQ(ierr);
5552   }
5553   PetscFunctionReturn(0);
5554 }
5555 
5556 
5557 
5558