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