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