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