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