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