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