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