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