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