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