xref: /petsc/src/ts/interface/ts.c (revision f6356ec75818945b8efe006dd9d896b209af0c61)
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, TSGLEE
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(), TSGetSolutionComponents()
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__ "TSGetSolutionComponents"
2250 /*@
2251    TSGetSolutionComponents - Returns any solution components at the present
2252    timestep, if available for the time integration method being used.
2253    Solution components are quantities that share the same size and
2254    structure as the solution vector.
2255 
2256    Not Collective, but Vec returned is parallel if TS is parallel
2257 
2258    Parameters :
2259 .  ts - the TS context obtained from TSCreate() (input parameter).
2260 .  n - If v is PETSC_NULL, then the number of solution components is
2261        returned through n, else the n-th solution component is
2262        returned in v.
2263 .  v - the vector containing the n-th solution component
2264        (may be PETSC_NULL to use this function to find out
2265         the number of solutions components).
2266 
2267    Level: advanced
2268 
2269 .seealso: TSGetSolution()
2270 
2271 .keywords: TS, timestep, get, solution
2272 @*/
2273 PetscErrorCode  TSGetSolutionComponents(TS ts,PetscInt *n,Vec *v)
2274 {
2275   PetscErrorCode ierr;
2276 
2277   PetscFunctionBegin;
2278   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
2279   if (!ts->ops->getsolutioncomponents) *n = 0;
2280   else {
2281     ierr = (*ts->ops->getsolutioncomponents)(ts,n,v);CHKERRQ(ierr);
2282   }
2283   PetscFunctionReturn(0);
2284 }
2285 
2286 #undef __FUNCT__
2287 #define __FUNCT__ "TSGetAuxSolution"
2288 /*@
2289    TSGetAuxSolution - Returns an auxiliary solution at the present
2290    timestep, if available for the time integration method being used.
2291 
2292    Not Collective, but Vec returned is parallel if TS is parallel
2293 
2294    Parameters :
2295 .  ts - the TS context obtained from TSCreate() (input parameter).
2296 .  v - the vector containing the auxiliary solution
2297 
2298    Level: intermediate
2299 
2300 .seealso: TSGetSolution()
2301 
2302 .keywords: TS, timestep, get, solution
2303 @*/
2304 PetscErrorCode  TSGetAuxSolution(TS ts,Vec *v)
2305 {
2306   PetscErrorCode ierr;
2307 
2308   PetscFunctionBegin;
2309   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
2310   if (ts->ops->getauxsolution) {
2311     ierr = (*ts->ops->getauxsolution)(ts,v);CHKERRQ(ierr);
2312   } else {
2313     ierr = VecZeroEntries(*v); CHKERRQ(ierr);
2314   }
2315   PetscFunctionReturn(0);
2316 }
2317 
2318 #undef __FUNCT__
2319 #define __FUNCT__ "TSGetTimeError"
2320 /*@
2321    TSGetTimeError - Returns the estimated error vector, if the chosen
2322    TSType has an error estimation functionality.
2323 
2324    Not Collective, but Vec returned is parallel if TS is parallel
2325 
2326    Parameters :
2327 .  ts - the TS context obtained from TSCreate() (input parameter).
2328 .  v - the vector containing the error (same size as the solution).
2329 
2330    Level: intermediate
2331 
2332 .seealso: TSGetSolution()
2333 
2334 .keywords: TS, timestep, get, error
2335 @*/
2336 PetscErrorCode  TSGetTimeError(TS ts,Vec *v)
2337 {
2338   PetscErrorCode ierr;
2339 
2340   PetscFunctionBegin;
2341   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
2342   if (ts->ops->gettimeerror) {
2343     ierr = (*ts->ops->gettimeerror)(ts,v);CHKERRQ(ierr);
2344   } else {
2345     ierr = VecZeroEntries(*v);CHKERRQ(ierr);
2346   }
2347   PetscFunctionReturn(0);
2348 }
2349 
2350 #undef __FUNCT__
2351 #define __FUNCT__ "TSGetCostGradients"
2352 /*@
2353    TSGetCostGradients - Returns the gradients from the TSAdjointSolve()
2354 
2355    Not Collective, but Vec returned is parallel if TS is parallel
2356 
2357    Input Parameter:
2358 .  ts - the TS context obtained from TSCreate()
2359 
2360    Output Parameter:
2361 +  lambda - vectors containing the gradients of the cost functions with respect to the ODE/DAE solution variables
2362 -  mu - vectors containing the gradients of the cost functions with respect to the problem parameters
2363 
2364    Level: intermediate
2365 
2366 .seealso: TSGetTimeStep()
2367 
2368 .keywords: TS, timestep, get, sensitivity
2369 @*/
2370 PetscErrorCode  TSGetCostGradients(TS ts,PetscInt *numcost,Vec **lambda,Vec **mu)
2371 {
2372   PetscFunctionBegin;
2373   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
2374   if (numcost) *numcost = ts->numcost;
2375   if (lambda)  *lambda  = ts->vecs_sensi;
2376   if (mu)      *mu      = ts->vecs_sensip;
2377   PetscFunctionReturn(0);
2378 }
2379 
2380 /* ----- Routines to initialize and destroy a timestepper ---- */
2381 #undef __FUNCT__
2382 #define __FUNCT__ "TSSetProblemType"
2383 /*@
2384   TSSetProblemType - Sets the type of problem to be solved.
2385 
2386   Not collective
2387 
2388   Input Parameters:
2389 + ts   - The TS
2390 - type - One of TS_LINEAR, TS_NONLINEAR where these types refer to problems of the forms
2391 .vb
2392          U_t - A U = 0      (linear)
2393          U_t - A(t) U = 0   (linear)
2394          F(t,U,U_t) = 0     (nonlinear)
2395 .ve
2396 
2397    Level: beginner
2398 
2399 .keywords: TS, problem type
2400 .seealso: TSSetUp(), TSProblemType, TS
2401 @*/
2402 PetscErrorCode  TSSetProblemType(TS ts, TSProblemType type)
2403 {
2404   PetscErrorCode ierr;
2405 
2406   PetscFunctionBegin;
2407   PetscValidHeaderSpecific(ts, TS_CLASSID,1);
2408   ts->problem_type = type;
2409   if (type == TS_LINEAR) {
2410     SNES snes;
2411     ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr);
2412     ierr = SNESSetType(snes,SNESKSPONLY);CHKERRQ(ierr);
2413   }
2414   PetscFunctionReturn(0);
2415 }
2416 
2417 #undef __FUNCT__
2418 #define __FUNCT__ "TSGetProblemType"
2419 /*@C
2420   TSGetProblemType - Gets the type of problem to be solved.
2421 
2422   Not collective
2423 
2424   Input Parameter:
2425 . ts   - The TS
2426 
2427   Output Parameter:
2428 . type - One of TS_LINEAR, TS_NONLINEAR where these types refer to problems of the forms
2429 .vb
2430          M U_t = A U
2431          M(t) U_t = A(t) U
2432          F(t,U,U_t)
2433 .ve
2434 
2435    Level: beginner
2436 
2437 .keywords: TS, problem type
2438 .seealso: TSSetUp(), TSProblemType, TS
2439 @*/
2440 PetscErrorCode  TSGetProblemType(TS ts, TSProblemType *type)
2441 {
2442   PetscFunctionBegin;
2443   PetscValidHeaderSpecific(ts, TS_CLASSID,1);
2444   PetscValidIntPointer(type,2);
2445   *type = ts->problem_type;
2446   PetscFunctionReturn(0);
2447 }
2448 
2449 #undef __FUNCT__
2450 #define __FUNCT__ "TSSetUp"
2451 /*@
2452    TSSetUp - Sets up the internal data structures for the later use
2453    of a timestepper.
2454 
2455    Collective on TS
2456 
2457    Input Parameter:
2458 .  ts - the TS context obtained from TSCreate()
2459 
2460    Notes:
2461    For basic use of the TS solvers the user need not explicitly call
2462    TSSetUp(), since these actions will automatically occur during
2463    the call to TSStep().  However, if one wishes to control this
2464    phase separately, TSSetUp() should be called after TSCreate()
2465    and optional routines of the form TSSetXXX(), but before TSStep().
2466 
2467    Level: advanced
2468 
2469 .keywords: TS, timestep, setup
2470 
2471 .seealso: TSCreate(), TSStep(), TSDestroy()
2472 @*/
2473 PetscErrorCode  TSSetUp(TS ts)
2474 {
2475   PetscErrorCode ierr;
2476   DM             dm;
2477   PetscErrorCode (*func)(SNES,Vec,Vec,void*);
2478   PetscErrorCode (*jac)(SNES,Vec,Mat,Mat,void*);
2479   TSIFunction    ifun;
2480   TSIJacobian    ijac;
2481   TSI2Jacobian   i2jac;
2482   TSRHSJacobian  rhsjac;
2483 
2484   PetscFunctionBegin;
2485   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
2486   if (ts->setupcalled) PetscFunctionReturn(0);
2487 
2488   ts->total_steps = 0;
2489   if (!((PetscObject)ts)->type_name) {
2490     ierr = TSGetIFunction(ts,NULL,&ifun,NULL);CHKERRQ(ierr);
2491     ierr = TSSetType(ts,ifun ? TSBEULER : TSEULER);CHKERRQ(ierr);
2492   }
2493 
2494   if (!ts->vec_sol) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Must call TSSetSolution() first");
2495 
2496   if (ts->rhsjacobian.reuse) {
2497     Mat Amat,Pmat;
2498     SNES snes;
2499     ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr);
2500     ierr = SNESGetJacobian(snes,&Amat,&Pmat,NULL,NULL);CHKERRQ(ierr);
2501     /* Matching matrices implies that an IJacobian is NOT set, because if it had been set, the IJacobian's matrix would
2502      * have displaced the RHS matrix */
2503     if (Amat == ts->Arhs) {
2504       ierr = MatDuplicate(ts->Arhs,MAT_DO_NOT_COPY_VALUES,&Amat);CHKERRQ(ierr);
2505       ierr = SNESSetJacobian(snes,Amat,NULL,NULL,NULL);CHKERRQ(ierr);
2506       ierr = MatDestroy(&Amat);CHKERRQ(ierr);
2507     }
2508     if (Pmat == ts->Brhs) {
2509       ierr = MatDuplicate(ts->Brhs,MAT_DO_NOT_COPY_VALUES,&Pmat);CHKERRQ(ierr);
2510       ierr = SNESSetJacobian(snes,NULL,Pmat,NULL,NULL);CHKERRQ(ierr);
2511       ierr = MatDestroy(&Pmat);CHKERRQ(ierr);
2512     }
2513   }
2514   if (ts->ops->setup) {
2515     ierr = (*ts->ops->setup)(ts);CHKERRQ(ierr);
2516   }
2517 
2518   /* In the case where we've set a DMTSFunction or what have you, we need the default SNESFunction
2519      to be set right but can't do it elsewhere due to the overreliance on ctx=ts.
2520    */
2521   ierr = TSGetDM(ts,&dm);CHKERRQ(ierr);
2522   ierr = DMSNESGetFunction(dm,&func,NULL);CHKERRQ(ierr);
2523   if (!func) {
2524     ierr = DMSNESSetFunction(dm,SNESTSFormFunction,ts);CHKERRQ(ierr);
2525   }
2526   /* If the SNES doesn't have a jacobian set and the TS has an ijacobian or rhsjacobian set, set the SNES to use it.
2527      Otherwise, the SNES will use coloring internally to form the Jacobian.
2528    */
2529   ierr = DMSNESGetJacobian(dm,&jac,NULL);CHKERRQ(ierr);
2530   ierr = DMTSGetIJacobian(dm,&ijac,NULL);CHKERRQ(ierr);
2531   ierr = DMTSGetI2Jacobian(dm,&i2jac,NULL);CHKERRQ(ierr);
2532   ierr = DMTSGetRHSJacobian(dm,&rhsjac,NULL);CHKERRQ(ierr);
2533   if (!jac && (ijac || i2jac || rhsjac)) {
2534     ierr = DMSNESSetJacobian(dm,SNESTSFormJacobian,ts);CHKERRQ(ierr);
2535   }
2536 
2537   /* if time integration scheme has a starting method, call it */
2538   if (ts->ops->startingmethod) {
2539     ierr = (*ts->ops->startingmethod)(ts);CHKERRQ(ierr);
2540   }
2541 
2542   ts->setupcalled = PETSC_TRUE;
2543   PetscFunctionReturn(0);
2544 }
2545 
2546 #undef __FUNCT__
2547 #define __FUNCT__ "TSAdjointSetUp"
2548 /*@
2549    TSAdjointSetUp - Sets up the internal data structures for the later use
2550    of an adjoint solver
2551 
2552    Collective on TS
2553 
2554    Input Parameter:
2555 .  ts - the TS context obtained from TSCreate()
2556 
2557    Level: advanced
2558 
2559 .keywords: TS, timestep, setup
2560 
2561 .seealso: TSCreate(), TSAdjointStep(), TSSetCostGradients()
2562 @*/
2563 PetscErrorCode  TSAdjointSetUp(TS ts)
2564 {
2565   PetscErrorCode ierr;
2566 
2567   PetscFunctionBegin;
2568   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
2569   if (ts->adjointsetupcalled) PetscFunctionReturn(0);
2570   if (!ts->vecs_sensi) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Must call TSSetCostGradients() first");
2571 
2572   if (ts->vec_costintegral) { /* if there is integral in the cost function*/
2573     ierr = VecDuplicateVecs(ts->vecs_sensi[0],ts->numcost,&ts->vecs_drdy);CHKERRQ(ierr);
2574     if (ts->vecs_sensip){
2575       ierr = VecDuplicateVecs(ts->vecs_sensip[0],ts->numcost,&ts->vecs_drdp);CHKERRQ(ierr);
2576     }
2577   }
2578 
2579   if (ts->ops->adjointsetup) {
2580     ierr = (*ts->ops->adjointsetup)(ts);CHKERRQ(ierr);
2581   }
2582   ts->adjointsetupcalled = PETSC_TRUE;
2583   PetscFunctionReturn(0);
2584 }
2585 
2586 #undef __FUNCT__
2587 #define __FUNCT__ "TSReset"
2588 /*@
2589    TSReset - Resets a TS context and removes any allocated Vecs and Mats.
2590 
2591    Collective on TS
2592 
2593    Input Parameter:
2594 .  ts - the TS context obtained from TSCreate()
2595 
2596    Level: beginner
2597 
2598 .keywords: TS, timestep, reset
2599 
2600 .seealso: TSCreate(), TSSetup(), TSDestroy()
2601 @*/
2602 PetscErrorCode  TSReset(TS ts)
2603 {
2604   PetscErrorCode ierr;
2605 
2606   PetscFunctionBegin;
2607   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
2608 
2609   if (ts->ops->reset) {
2610     ierr = (*ts->ops->reset)(ts);CHKERRQ(ierr);
2611   }
2612   if (ts->snes) {ierr = SNESReset(ts->snes);CHKERRQ(ierr);}
2613   if (ts->adapt) {ierr = TSAdaptReset(ts->adapt);CHKERRQ(ierr);}
2614 
2615   ierr = MatDestroy(&ts->Arhs);CHKERRQ(ierr);
2616   ierr = MatDestroy(&ts->Brhs);CHKERRQ(ierr);
2617   ierr = VecDestroy(&ts->Frhs);CHKERRQ(ierr);
2618   ierr = VecDestroy(&ts->vec_sol);CHKERRQ(ierr);
2619   ierr = VecDestroy(&ts->vec_dot);CHKERRQ(ierr);
2620   ierr = VecDestroy(&ts->vatol);CHKERRQ(ierr);
2621   ierr = VecDestroy(&ts->vrtol);CHKERRQ(ierr);
2622   ierr = VecDestroyVecs(ts->nwork,&ts->work);CHKERRQ(ierr);
2623 
2624  if (ts->vec_costintegral) {
2625     ierr = VecDestroyVecs(ts->numcost,&ts->vecs_drdy);CHKERRQ(ierr);
2626     if (ts->vecs_drdp){
2627       ierr = VecDestroyVecs(ts->numcost,&ts->vecs_drdp);CHKERRQ(ierr);
2628     }
2629   }
2630   ts->vecs_sensi  = NULL;
2631   ts->vecs_sensip = NULL;
2632   ierr = MatDestroy(&ts->Jacp);CHKERRQ(ierr);
2633   ierr = VecDestroy(&ts->vec_costintegral);CHKERRQ(ierr);
2634   ierr = VecDestroy(&ts->vec_costintegrand);CHKERRQ(ierr);
2635   ts->setupcalled = PETSC_FALSE;
2636   PetscFunctionReturn(0);
2637 }
2638 
2639 #undef __FUNCT__
2640 #define __FUNCT__ "TSDestroy"
2641 /*@
2642    TSDestroy - Destroys the timestepper context that was created
2643    with TSCreate().
2644 
2645    Collective on TS
2646 
2647    Input Parameter:
2648 .  ts - the TS context obtained from TSCreate()
2649 
2650    Level: beginner
2651 
2652 .keywords: TS, timestepper, destroy
2653 
2654 .seealso: TSCreate(), TSSetUp(), TSSolve()
2655 @*/
2656 PetscErrorCode  TSDestroy(TS *ts)
2657 {
2658   PetscErrorCode ierr;
2659 
2660   PetscFunctionBegin;
2661   if (!*ts) PetscFunctionReturn(0);
2662   PetscValidHeaderSpecific((*ts),TS_CLASSID,1);
2663   if (--((PetscObject)(*ts))->refct > 0) {*ts = 0; PetscFunctionReturn(0);}
2664 
2665   ierr = TSReset((*ts));CHKERRQ(ierr);
2666 
2667   /* if memory was published with SAWs then destroy it */
2668   ierr = PetscObjectSAWsViewOff((PetscObject)*ts);CHKERRQ(ierr);
2669   if ((*ts)->ops->destroy) {ierr = (*(*ts)->ops->destroy)((*ts));CHKERRQ(ierr);}
2670 
2671   ierr = TSTrajectoryDestroy(&(*ts)->trajectory);CHKERRQ(ierr);
2672 
2673   ierr = TSAdaptDestroy(&(*ts)->adapt);CHKERRQ(ierr);
2674   ierr = TSEventDestroy(&(*ts)->event);CHKERRQ(ierr);
2675 
2676   ierr = SNESDestroy(&(*ts)->snes);CHKERRQ(ierr);
2677   ierr = DMDestroy(&(*ts)->dm);CHKERRQ(ierr);
2678   ierr = TSMonitorCancel((*ts));CHKERRQ(ierr);
2679   ierr = TSAdjointMonitorCancel((*ts));CHKERRQ(ierr);
2680 
2681   ierr = PetscHeaderDestroy(ts);CHKERRQ(ierr);
2682   PetscFunctionReturn(0);
2683 }
2684 
2685 #undef __FUNCT__
2686 #define __FUNCT__ "TSGetSNES"
2687 /*@
2688    TSGetSNES - Returns the SNES (nonlinear solver) associated with
2689    a TS (timestepper) context. Valid only for nonlinear problems.
2690 
2691    Not Collective, but SNES is parallel if TS is parallel
2692 
2693    Input Parameter:
2694 .  ts - the TS context obtained from TSCreate()
2695 
2696    Output Parameter:
2697 .  snes - the nonlinear solver context
2698 
2699    Notes:
2700    The user can then directly manipulate the SNES context to set various
2701    options, etc.  Likewise, the user can then extract and manipulate the
2702    KSP, KSP, and PC contexts as well.
2703 
2704    TSGetSNES() does not work for integrators that do not use SNES; in
2705    this case TSGetSNES() returns NULL in snes.
2706 
2707    Level: beginner
2708 
2709 .keywords: timestep, get, SNES
2710 @*/
2711 PetscErrorCode  TSGetSNES(TS ts,SNES *snes)
2712 {
2713   PetscErrorCode ierr;
2714 
2715   PetscFunctionBegin;
2716   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
2717   PetscValidPointer(snes,2);
2718   if (!ts->snes) {
2719     ierr = SNESCreate(PetscObjectComm((PetscObject)ts),&ts->snes);CHKERRQ(ierr);
2720     ierr = SNESSetFunction(ts->snes,NULL,SNESTSFormFunction,ts);CHKERRQ(ierr);
2721     ierr = PetscLogObjectParent((PetscObject)ts,(PetscObject)ts->snes);CHKERRQ(ierr);
2722     ierr = PetscObjectIncrementTabLevel((PetscObject)ts->snes,(PetscObject)ts,1);CHKERRQ(ierr);
2723     if (ts->dm) {ierr = SNESSetDM(ts->snes,ts->dm);CHKERRQ(ierr);}
2724     if (ts->problem_type == TS_LINEAR) {
2725       ierr = SNESSetType(ts->snes,SNESKSPONLY);CHKERRQ(ierr);
2726     }
2727   }
2728   *snes = ts->snes;
2729   PetscFunctionReturn(0);
2730 }
2731 
2732 #undef __FUNCT__
2733 #define __FUNCT__ "TSSetSNES"
2734 /*@
2735    TSSetSNES - Set the SNES (nonlinear solver) to be used by the timestepping context
2736 
2737    Collective
2738 
2739    Input Parameter:
2740 +  ts - the TS context obtained from TSCreate()
2741 -  snes - the nonlinear solver context
2742 
2743    Notes:
2744    Most users should have the TS created by calling TSGetSNES()
2745 
2746    Level: developer
2747 
2748 .keywords: timestep, set, SNES
2749 @*/
2750 PetscErrorCode TSSetSNES(TS ts,SNES snes)
2751 {
2752   PetscErrorCode ierr;
2753   PetscErrorCode (*func)(SNES,Vec,Mat,Mat,void*);
2754 
2755   PetscFunctionBegin;
2756   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
2757   PetscValidHeaderSpecific(snes,SNES_CLASSID,2);
2758   ierr = PetscObjectReference((PetscObject)snes);CHKERRQ(ierr);
2759   ierr = SNESDestroy(&ts->snes);CHKERRQ(ierr);
2760 
2761   ts->snes = snes;
2762 
2763   ierr = SNESSetFunction(ts->snes,NULL,SNESTSFormFunction,ts);CHKERRQ(ierr);
2764   ierr = SNESGetJacobian(ts->snes,NULL,NULL,&func,NULL);CHKERRQ(ierr);
2765   if (func == SNESTSFormJacobian) {
2766     ierr = SNESSetJacobian(ts->snes,NULL,NULL,SNESTSFormJacobian,ts);CHKERRQ(ierr);
2767   }
2768   PetscFunctionReturn(0);
2769 }
2770 
2771 #undef __FUNCT__
2772 #define __FUNCT__ "TSGetKSP"
2773 /*@
2774    TSGetKSP - Returns the KSP (linear solver) associated with
2775    a TS (timestepper) context.
2776 
2777    Not Collective, but KSP is parallel if TS is parallel
2778 
2779    Input Parameter:
2780 .  ts - the TS context obtained from TSCreate()
2781 
2782    Output Parameter:
2783 .  ksp - the nonlinear solver context
2784 
2785    Notes:
2786    The user can then directly manipulate the KSP context to set various
2787    options, etc.  Likewise, the user can then extract and manipulate the
2788    KSP and PC contexts as well.
2789 
2790    TSGetKSP() does not work for integrators that do not use KSP;
2791    in this case TSGetKSP() returns NULL in ksp.
2792 
2793    Level: beginner
2794 
2795 .keywords: timestep, get, KSP
2796 @*/
2797 PetscErrorCode  TSGetKSP(TS ts,KSP *ksp)
2798 {
2799   PetscErrorCode ierr;
2800   SNES           snes;
2801 
2802   PetscFunctionBegin;
2803   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
2804   PetscValidPointer(ksp,2);
2805   if (!((PetscObject)ts)->type_name) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"KSP is not created yet. Call TSSetType() first");
2806   if (ts->problem_type != TS_LINEAR) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Linear only; use TSGetSNES()");
2807   ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr);
2808   ierr = SNESGetKSP(snes,ksp);CHKERRQ(ierr);
2809   PetscFunctionReturn(0);
2810 }
2811 
2812 /* ----------- Routines to set solver parameters ---------- */
2813 
2814 #undef __FUNCT__
2815 #define __FUNCT__ "TSGetDuration"
2816 /*@
2817    TSGetDuration - Gets the maximum number of timesteps to use and
2818    maximum time for iteration.
2819 
2820    Not Collective
2821 
2822    Input Parameters:
2823 +  ts       - the TS context obtained from TSCreate()
2824 .  maxsteps - maximum number of iterations to use, or NULL
2825 -  maxtime  - final time to iterate to, or NULL
2826 
2827    Level: intermediate
2828 
2829 .keywords: TS, timestep, get, maximum, iterations, time
2830 @*/
2831 PetscErrorCode  TSGetDuration(TS ts, PetscInt *maxsteps, PetscReal *maxtime)
2832 {
2833   PetscFunctionBegin;
2834   PetscValidHeaderSpecific(ts, TS_CLASSID,1);
2835   if (maxsteps) {
2836     PetscValidIntPointer(maxsteps,2);
2837     *maxsteps = ts->max_steps;
2838   }
2839   if (maxtime) {
2840     PetscValidScalarPointer(maxtime,3);
2841     *maxtime = ts->max_time;
2842   }
2843   PetscFunctionReturn(0);
2844 }
2845 
2846 #undef __FUNCT__
2847 #define __FUNCT__ "TSSetDuration"
2848 /*@
2849    TSSetDuration - Sets the maximum number of timesteps to use and
2850    maximum time for iteration.
2851 
2852    Logically Collective on TS
2853 
2854    Input Parameters:
2855 +  ts - the TS context obtained from TSCreate()
2856 .  maxsteps - maximum number of iterations to use
2857 -  maxtime - final time to iterate to
2858 
2859    Options Database Keys:
2860 .  -ts_max_steps <maxsteps> - Sets maxsteps
2861 .  -ts_final_time <maxtime> - Sets maxtime
2862 
2863    Notes:
2864    The default maximum number of iterations is 5000. Default time is 5.0
2865 
2866    Level: intermediate
2867 
2868 .keywords: TS, timestep, set, maximum, iterations
2869 
2870 .seealso: TSSetExactFinalTime()
2871 @*/
2872 PetscErrorCode  TSSetDuration(TS ts,PetscInt maxsteps,PetscReal maxtime)
2873 {
2874   PetscFunctionBegin;
2875   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
2876   PetscValidLogicalCollectiveInt(ts,maxsteps,2);
2877   PetscValidLogicalCollectiveReal(ts,maxtime,2);
2878   if (maxsteps >= 0) ts->max_steps = maxsteps;
2879   if (maxtime != PETSC_DEFAULT) ts->max_time = maxtime;
2880   PetscFunctionReturn(0);
2881 }
2882 
2883 #undef __FUNCT__
2884 #define __FUNCT__ "TSSetSolution"
2885 /*@
2886    TSSetSolution - Sets the initial solution vector
2887    for use by the TS routines.
2888 
2889    Logically Collective on TS and Vec
2890 
2891    Input Parameters:
2892 +  ts - the TS context obtained from TSCreate()
2893 -  u - the solution vector
2894 
2895    Level: beginner
2896 
2897 .keywords: TS, timestep, set, solution, initial conditions
2898 @*/
2899 PetscErrorCode  TSSetSolution(TS ts,Vec u)
2900 {
2901   PetscErrorCode ierr;
2902   DM             dm;
2903 
2904   PetscFunctionBegin;
2905   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
2906   PetscValidHeaderSpecific(u,VEC_CLASSID,2);
2907   ierr = PetscObjectReference((PetscObject)u);CHKERRQ(ierr);
2908   ierr = VecDestroy(&ts->vec_sol);CHKERRQ(ierr);
2909   ts->vec_sol = u;
2910 
2911   ierr = TSGetDM(ts,&dm);CHKERRQ(ierr);
2912   ierr = DMShellSetGlobalVector(dm,u);CHKERRQ(ierr);
2913   PetscFunctionReturn(0);
2914 }
2915 
2916 #undef __FUNCT__
2917 #define __FUNCT__ "TSAdjointSetSteps"
2918 /*@
2919    TSAdjointSetSteps - Sets the number of steps the adjoint solver should take backward in time
2920 
2921    Logically Collective on TS
2922 
2923    Input Parameters:
2924 +  ts - the TS context obtained from TSCreate()
2925 .  steps - number of steps to use
2926 
2927    Level: intermediate
2928 
2929    Notes: Normally one does not call this and TSAdjointSolve() integrates back to the original timestep. One can call this
2930           so as to integrate back to less than the original timestep
2931 
2932 .keywords: TS, timestep, set, maximum, iterations
2933 
2934 .seealso: TSSetExactFinalTime()
2935 @*/
2936 PetscErrorCode  TSAdjointSetSteps(TS ts,PetscInt steps)
2937 {
2938   PetscFunctionBegin;
2939   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
2940   PetscValidLogicalCollectiveInt(ts,steps,2);
2941   if (steps < 0) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_ARG_OUTOFRANGE,"Cannot step back a negative number of steps");
2942   if (steps > ts->total_steps) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_ARG_OUTOFRANGE,"Cannot step back more than the total number of forward steps");
2943   ts->adjoint_max_steps = steps;
2944   PetscFunctionReturn(0);
2945 }
2946 
2947 #undef __FUNCT__
2948 #define __FUNCT__ "TSSetCostGradients"
2949 /*@
2950    TSSetCostGradients - Sets the initial value of the gradients of the cost function w.r.t. initial conditions and w.r.t. the problem parameters
2951       for use by the TSAdjoint routines.
2952 
2953    Logically Collective on TS and Vec
2954 
2955    Input Parameters:
2956 +  ts - the TS context obtained from TSCreate()
2957 .  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
2958 -  mu - gradients with respect to the parameters, the number of entries in these vectors is the same as the number of parameters
2959 
2960    Level: beginner
2961 
2962    Notes: the entries in these vectors must be correctly initialized with the values lamda_i = df/dy|finaltime  mu_i = df/dp|finaltime
2963 
2964 .keywords: TS, timestep, set, sensitivity, initial conditions
2965 @*/
2966 PetscErrorCode  TSSetCostGradients(TS ts,PetscInt numcost,Vec *lambda,Vec *mu)
2967 {
2968   PetscFunctionBegin;
2969   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
2970   PetscValidPointer(lambda,2);
2971   ts->vecs_sensi  = lambda;
2972   ts->vecs_sensip = mu;
2973   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");
2974   ts->numcost  = numcost;
2975   PetscFunctionReturn(0);
2976 }
2977 
2978 #undef __FUNCT__
2979 #define __FUNCT__ "TSAdjointSetRHSJacobian"
2980 /*@C
2981   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.
2982 
2983   Logically Collective on TS
2984 
2985   Input Parameters:
2986 + ts   - The TS context obtained from TSCreate()
2987 - func - The function
2988 
2989   Calling sequence of func:
2990 $ func (TS ts,PetscReal t,Vec y,Mat A,void *ctx);
2991 +   t - current timestep
2992 .   y - input vector (current ODE solution)
2993 .   A - output matrix
2994 -   ctx - [optional] user-defined function context
2995 
2996   Level: intermediate
2997 
2998   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
2999 
3000 .keywords: TS, sensitivity
3001 .seealso:
3002 @*/
3003 PetscErrorCode  TSAdjointSetRHSJacobian(TS ts,Mat Amat,PetscErrorCode (*func)(TS,PetscReal,Vec,Mat,void*),void *ctx)
3004 {
3005   PetscErrorCode ierr;
3006 
3007   PetscFunctionBegin;
3008   PetscValidHeaderSpecific(ts, TS_CLASSID,1);
3009   if (Amat) PetscValidHeaderSpecific(Amat,MAT_CLASSID,2);
3010 
3011   ts->rhsjacobianp    = func;
3012   ts->rhsjacobianpctx = ctx;
3013   if(Amat) {
3014     ierr = PetscObjectReference((PetscObject)Amat);CHKERRQ(ierr);
3015     ierr = MatDestroy(&ts->Jacp);CHKERRQ(ierr);
3016     ts->Jacp = Amat;
3017   }
3018   PetscFunctionReturn(0);
3019 }
3020 
3021 #undef __FUNCT__
3022 #define __FUNCT__ "TSAdjointComputeRHSJacobian"
3023 /*@C
3024   TSAdjointComputeRHSJacobian - Runs the user-defined Jacobian function.
3025 
3026   Collective on TS
3027 
3028   Input Parameters:
3029 . ts   - The TS context obtained from TSCreate()
3030 
3031   Level: developer
3032 
3033 .keywords: TS, sensitivity
3034 .seealso: TSAdjointSetRHSJacobian()
3035 @*/
3036 PetscErrorCode  TSAdjointComputeRHSJacobian(TS ts,PetscReal t,Vec X,Mat Amat)
3037 {
3038   PetscErrorCode ierr;
3039 
3040   PetscFunctionBegin;
3041   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
3042   PetscValidHeaderSpecific(X,VEC_CLASSID,3);
3043   PetscValidPointer(Amat,4);
3044 
3045   PetscStackPush("TS user JacobianP function for sensitivity analysis");
3046   ierr = (*ts->rhsjacobianp)(ts,t,X,Amat,ts->rhsjacobianpctx); CHKERRQ(ierr);
3047   PetscStackPop;
3048   PetscFunctionReturn(0);
3049 }
3050 
3051 #undef __FUNCT__
3052 #define __FUNCT__ "TSSetCostIntegrand"
3053 /*@C
3054     TSSetCostIntegrand - Sets the routine for evaluating the integral term in one or more cost functions
3055 
3056     Logically Collective on TS
3057 
3058     Input Parameters:
3059 +   ts - the TS context obtained from TSCreate()
3060 .   numcost - number of gradients to be computed, this is the number of cost functions
3061 .   rf - routine for evaluating the integrand function
3062 .   drdyf - function that computes the gradients of the r's with respect to y,NULL if not a function y
3063 .   drdpf - function that computes the gradients of the r's with respect to p, NULL if not a function of p
3064 .   fwd - flag indicating whether to evaluate cost integral in the forward run or the adjoint run
3065 -   ctx - [optional] user-defined context for private data for the function evaluation routine (may be NULL)
3066 
3067     Calling sequence of rf:
3068 $     rf(TS ts,PetscReal t,Vec y,Vec f[],void *ctx);
3069 
3070 +   t - current timestep
3071 .   y - input vector
3072 .   f - function result; one vector entry for each cost function
3073 -   ctx - [optional] user-defined function context
3074 
3075    Calling sequence of drdyf:
3076 $    PetscErroCode drdyf(TS ts,PetscReal t,Vec y,Vec *drdy,void *ctx);
3077 
3078    Calling sequence of drdpf:
3079 $    PetscErroCode drdpf(TS ts,PetscReal t,Vec y,Vec *drdp,void *ctx);
3080 
3081     Level: intermediate
3082 
3083     Notes: For optimization there is generally a single cost function, numcost = 1. For sensitivities there may be multiple cost functions
3084 
3085 .keywords: TS, sensitivity analysis, timestep, set, quadrature, function
3086 
3087 .seealso: TSAdjointSetRHSJacobian(),TSGetCostGradients(), TSSetCostGradients()
3088 @*/
3089 PetscErrorCode  TSSetCostIntegrand(TS ts,PetscInt numcost,PetscErrorCode (*rf)(TS,PetscReal,Vec,Vec,void*),
3090                                                           PetscErrorCode (*drdyf)(TS,PetscReal,Vec,Vec*,void*),
3091                                                           PetscErrorCode (*drdpf)(TS,PetscReal,Vec,Vec*,void*),
3092                                                           PetscBool fwd,void *ctx)
3093 {
3094   PetscErrorCode ierr;
3095 
3096   PetscFunctionBegin;
3097   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
3098   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()");
3099   if (!ts->numcost) ts->numcost=numcost;
3100 
3101   ts->costintegralfwd  = fwd; /* Evaluate the cost integral in forward run if fwd is true */
3102   ierr                 = VecCreateSeq(PETSC_COMM_SELF,numcost,&ts->vec_costintegral);CHKERRQ(ierr);
3103   ierr                 = VecDuplicate(ts->vec_costintegral,&ts->vec_costintegrand);CHKERRQ(ierr);
3104   ts->costintegrand    = rf;
3105   ts->costintegrandctx = ctx;
3106   ts->drdyfunction     = drdyf;
3107   ts->drdpfunction     = drdpf;
3108   PetscFunctionReturn(0);
3109 }
3110 
3111 #undef __FUNCT__
3112 #define __FUNCT__ "TSGetCostIntegral"
3113 /*@
3114    TSGetCostIntegral - Returns the values of the integral term in the cost functions.
3115    It is valid to call the routine after a backward run.
3116 
3117    Not Collective
3118 
3119    Input Parameter:
3120 .  ts - the TS context obtained from TSCreate()
3121 
3122    Output Parameter:
3123 .  v - the vector containing the integrals for each cost function
3124 
3125    Level: intermediate
3126 
3127 .seealso: TSSetCostIntegrand()
3128 
3129 .keywords: TS, sensitivity analysis
3130 @*/
3131 PetscErrorCode  TSGetCostIntegral(TS ts,Vec *v)
3132 {
3133   PetscFunctionBegin;
3134   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
3135   PetscValidPointer(v,2);
3136   *v = ts->vec_costintegral;
3137   PetscFunctionReturn(0);
3138 }
3139 
3140 #undef __FUNCT__
3141 #define __FUNCT__ "TSAdjointComputeCostIntegrand"
3142 /*@
3143    TSAdjointComputeCostIntegrand - Evaluates the integral function in the cost functions.
3144 
3145    Input Parameters:
3146 +  ts - the TS context
3147 .  t - current time
3148 -  y - state vector, i.e. current solution
3149 
3150    Output Parameter:
3151 .  q - vector of size numcost to hold the outputs
3152 
3153    Note:
3154    Most users should not need to explicitly call this routine, as it
3155    is used internally within the sensitivity analysis context.
3156 
3157    Level: developer
3158 
3159 .keywords: TS, compute
3160 
3161 .seealso: TSSetCostIntegrand()
3162 @*/
3163 PetscErrorCode TSAdjointComputeCostIntegrand(TS ts,PetscReal t,Vec y,Vec q)
3164 {
3165   PetscErrorCode ierr;
3166 
3167   PetscFunctionBegin;
3168   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
3169   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
3170   PetscValidHeaderSpecific(q,VEC_CLASSID,4);
3171 
3172   ierr = PetscLogEventBegin(TS_FunctionEval,ts,y,q,0);CHKERRQ(ierr);
3173   if (ts->costintegrand) {
3174     PetscStackPush("TS user integrand in the cost function");
3175     ierr = (*ts->costintegrand)(ts,t,y,q,ts->costintegrandctx);CHKERRQ(ierr);
3176     PetscStackPop;
3177   } else {
3178     ierr = VecZeroEntries(q);CHKERRQ(ierr);
3179   }
3180 
3181   ierr = PetscLogEventEnd(TS_FunctionEval,ts,y,q,0);CHKERRQ(ierr);
3182   PetscFunctionReturn(0);
3183 }
3184 
3185 #undef __FUNCT__
3186 #define __FUNCT__ "TSAdjointComputeDRDYFunction"
3187 /*@
3188   TSAdjointComputeDRDYFunction - Runs the user-defined DRDY function.
3189 
3190   Collective on TS
3191 
3192   Input Parameters:
3193 . ts   - The TS context obtained from TSCreate()
3194 
3195   Notes:
3196   TSAdjointComputeDRDYFunction() is typically used for sensitivity implementation,
3197   so most users would not generally call this routine themselves.
3198 
3199   Level: developer
3200 
3201 .keywords: TS, sensitivity
3202 .seealso: TSAdjointComputeDRDYFunction()
3203 @*/
3204 PetscErrorCode  TSAdjointComputeDRDYFunction(TS ts,PetscReal t,Vec y,Vec *drdy)
3205 {
3206   PetscErrorCode ierr;
3207 
3208   PetscFunctionBegin;
3209   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
3210   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
3211 
3212   PetscStackPush("TS user DRDY function for sensitivity analysis");
3213   ierr = (*ts->drdyfunction)(ts,t,y,drdy,ts->costintegrandctx); CHKERRQ(ierr);
3214   PetscStackPop;
3215   PetscFunctionReturn(0);
3216 }
3217 
3218 #undef __FUNCT__
3219 #define __FUNCT__ "TSAdjointComputeDRDPFunction"
3220 /*@
3221   TSAdjointComputeDRDPFunction - Runs the user-defined DRDP function.
3222 
3223   Collective on TS
3224 
3225   Input Parameters:
3226 . ts   - The TS context obtained from TSCreate()
3227 
3228   Notes:
3229   TSDRDPFunction() is typically used for sensitivity implementation,
3230   so most users would not generally call this routine themselves.
3231 
3232   Level: developer
3233 
3234 .keywords: TS, sensitivity
3235 .seealso: TSAdjointSetDRDPFunction()
3236 @*/
3237 PetscErrorCode  TSAdjointComputeDRDPFunction(TS ts,PetscReal t,Vec y,Vec *drdp)
3238 {
3239   PetscErrorCode ierr;
3240 
3241   PetscFunctionBegin;
3242   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
3243   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
3244 
3245   PetscStackPush("TS user DRDP function for sensitivity analysis");
3246   ierr = (*ts->drdpfunction)(ts,t,y,drdp,ts->costintegrandctx); CHKERRQ(ierr);
3247   PetscStackPop;
3248   PetscFunctionReturn(0);
3249 }
3250 
3251 #undef __FUNCT__
3252 #define __FUNCT__ "TSSetPreStep"
3253 /*@C
3254   TSSetPreStep - Sets the general-purpose function
3255   called once at the beginning of each time step.
3256 
3257   Logically Collective on TS
3258 
3259   Input Parameters:
3260 + ts   - The TS context obtained from TSCreate()
3261 - func - The function
3262 
3263   Calling sequence of func:
3264 . func (TS ts);
3265 
3266   Level: intermediate
3267 
3268   Note:
3269   If a step is rejected, TSStep() will call this routine again before each attempt.
3270   The last completed time step number can be queried using TSGetTimeStepNumber(), the
3271   size of the step being attempted can be obtained using TSGetTimeStep().
3272 
3273 .keywords: TS, timestep
3274 .seealso: TSSetPreStage(), TSSetPostStage(), TSSetPostStep(), TSStep()
3275 @*/
3276 PetscErrorCode  TSSetPreStep(TS ts, PetscErrorCode (*func)(TS))
3277 {
3278   PetscFunctionBegin;
3279   PetscValidHeaderSpecific(ts, TS_CLASSID,1);
3280   ts->prestep = func;
3281   PetscFunctionReturn(0);
3282 }
3283 
3284 #undef __FUNCT__
3285 #define __FUNCT__ "TSPreStep"
3286 /*@
3287   TSPreStep - Runs the user-defined pre-step function.
3288 
3289   Collective on TS
3290 
3291   Input Parameters:
3292 . ts   - The TS context obtained from TSCreate()
3293 
3294   Notes:
3295   TSPreStep() is typically used within time stepping implementations,
3296   so most users would not generally call this routine themselves.
3297 
3298   Level: developer
3299 
3300 .keywords: TS, timestep
3301 .seealso: TSSetPreStep(), TSPreStage(), TSPostStage(), TSPostStep()
3302 @*/
3303 PetscErrorCode  TSPreStep(TS ts)
3304 {
3305   PetscErrorCode ierr;
3306 
3307   PetscFunctionBegin;
3308   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
3309   if (ts->prestep) {
3310     PetscStackCallStandard((*ts->prestep),(ts));
3311   }
3312   PetscFunctionReturn(0);
3313 }
3314 
3315 #undef __FUNCT__
3316 #define __FUNCT__ "TSSetPreStage"
3317 /*@C
3318   TSSetPreStage - Sets the general-purpose function
3319   called once at the beginning of each stage.
3320 
3321   Logically Collective on TS
3322 
3323   Input Parameters:
3324 + ts   - The TS context obtained from TSCreate()
3325 - func - The function
3326 
3327   Calling sequence of func:
3328 . PetscErrorCode func(TS ts, PetscReal stagetime);
3329 
3330   Level: intermediate
3331 
3332   Note:
3333   There may be several stages per time step. If the solve for a given stage fails, the step may be rejected and retried.
3334   The time step number being computed can be queried using TSGetTimeStepNumber() and the total size of the step being
3335   attempted can be obtained using TSGetTimeStep(). The time at the start of the step is available via TSGetTime().
3336 
3337 .keywords: TS, timestep
3338 .seealso: TSSetPostStage(), TSSetPreStep(), TSSetPostStep(), TSGetApplicationContext()
3339 @*/
3340 PetscErrorCode  TSSetPreStage(TS ts, PetscErrorCode (*func)(TS,PetscReal))
3341 {
3342   PetscFunctionBegin;
3343   PetscValidHeaderSpecific(ts, TS_CLASSID,1);
3344   ts->prestage = func;
3345   PetscFunctionReturn(0);
3346 }
3347 
3348 #undef __FUNCT__
3349 #define __FUNCT__ "TSSetPostStage"
3350 /*@C
3351   TSSetPostStage - Sets the general-purpose function
3352   called once at the end of each stage.
3353 
3354   Logically Collective on TS
3355 
3356   Input Parameters:
3357 + ts   - The TS context obtained from TSCreate()
3358 - func - The function
3359 
3360   Calling sequence of func:
3361 . PetscErrorCode func(TS ts, PetscReal stagetime, PetscInt stageindex, Vec* Y);
3362 
3363   Level: intermediate
3364 
3365   Note:
3366   There may be several stages per time step. If the solve for a given stage fails, the step may be rejected and retried.
3367   The time step number being computed can be queried using TSGetTimeStepNumber() and the total size of the step being
3368   attempted can be obtained using TSGetTimeStep(). The time at the start of the step is available via TSGetTime().
3369 
3370 .keywords: TS, timestep
3371 .seealso: TSSetPreStage(), TSSetPreStep(), TSSetPostStep(), TSGetApplicationContext()
3372 @*/
3373 PetscErrorCode  TSSetPostStage(TS ts, PetscErrorCode (*func)(TS,PetscReal,PetscInt,Vec*))
3374 {
3375   PetscFunctionBegin;
3376   PetscValidHeaderSpecific(ts, TS_CLASSID,1);
3377   ts->poststage = func;
3378   PetscFunctionReturn(0);
3379 }
3380 
3381 #undef __FUNCT__
3382 #define __FUNCT__ "TSSetPostEvaluate"
3383 /*@C
3384   TSSetPostEvaluate - Sets the general-purpose function
3385   called once at the end of each step evaluation.
3386 
3387   Logically Collective on TS
3388 
3389   Input Parameters:
3390 + ts   - The TS context obtained from TSCreate()
3391 - func - The function
3392 
3393   Calling sequence of func:
3394 . PetscErrorCode func(TS ts);
3395 
3396   Level: intermediate
3397 
3398   Note:
3399   Semantically, TSSetPostEvaluate() differs from TSSetPostStep() since the function it sets is called before event-handling
3400   thus guaranteeing the same solution (computed by the time-stepper) will be passed to it. On the other hand, TSPostStep()
3401   may be passed a different solution, possibly changed by the event handler. TSPostEvaluate() is called after the next step
3402   solution is evaluated allowing to modify it, if need be. The solution can be obtained with TSGetSolution(), the time step
3403   with TSGetTimeStep(), and the time at the start of the step is available via TSGetTime()
3404 
3405 .keywords: TS, timestep
3406 .seealso: TSSetPreStage(), TSSetPreStep(), TSSetPostStep(), TSGetApplicationContext()
3407 @*/
3408 PetscErrorCode  TSSetPostEvaluate(TS ts, PetscErrorCode (*func)(TS))
3409 {
3410   PetscFunctionBegin;
3411   PetscValidHeaderSpecific(ts, TS_CLASSID,1);
3412   ts->postevaluate = func;
3413   PetscFunctionReturn(0);
3414 }
3415 
3416 #undef __FUNCT__
3417 #define __FUNCT__ "TSPreStage"
3418 /*@
3419   TSPreStage - Runs the user-defined pre-stage function set using TSSetPreStage()
3420 
3421   Collective on TS
3422 
3423   Input Parameters:
3424 . ts          - The TS context obtained from TSCreate()
3425   stagetime   - The absolute time of the current stage
3426 
3427   Notes:
3428   TSPreStage() is typically used within time stepping implementations,
3429   most users would not generally call this routine themselves.
3430 
3431   Level: developer
3432 
3433 .keywords: TS, timestep
3434 .seealso: TSPostStage(), TSSetPreStep(), TSPreStep(), TSPostStep()
3435 @*/
3436 PetscErrorCode  TSPreStage(TS ts, PetscReal stagetime)
3437 {
3438   PetscErrorCode ierr;
3439 
3440   PetscFunctionBegin;
3441   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
3442   if (ts->prestage) {
3443     PetscStackCallStandard((*ts->prestage),(ts,stagetime));
3444   }
3445   PetscFunctionReturn(0);
3446 }
3447 
3448 #undef __FUNCT__
3449 #define __FUNCT__ "TSPostStage"
3450 /*@
3451   TSPostStage - Runs the user-defined post-stage function set using TSSetPostStage()
3452 
3453   Collective on TS
3454 
3455   Input Parameters:
3456 . ts          - The TS context obtained from TSCreate()
3457   stagetime   - The absolute time of the current stage
3458   stageindex  - Stage number
3459   Y           - Array of vectors (of size = total number
3460                 of stages) with the stage solutions
3461 
3462   Notes:
3463   TSPostStage() is typically used within time stepping implementations,
3464   most users would not generally call this routine themselves.
3465 
3466   Level: developer
3467 
3468 .keywords: TS, timestep
3469 .seealso: TSPreStage(), TSSetPreStep(), TSPreStep(), TSPostStep()
3470 @*/
3471 PetscErrorCode  TSPostStage(TS ts, PetscReal stagetime, PetscInt stageindex, Vec *Y)
3472 {
3473   PetscErrorCode ierr;
3474 
3475   PetscFunctionBegin;
3476   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
3477   if (ts->poststage) {
3478     PetscStackCallStandard((*ts->poststage),(ts,stagetime,stageindex,Y));
3479   }
3480   PetscFunctionReturn(0);
3481 }
3482 
3483 #undef __FUNCT__
3484 #define __FUNCT__ "TSPostEvaluate"
3485 /*@
3486   TSPostEvaluate - Runs the user-defined post-evaluate function set using TSSetPostEvaluate()
3487 
3488   Collective on TS
3489 
3490   Input Parameters:
3491 . ts          - The TS context obtained from TSCreate()
3492 
3493   Notes:
3494   TSPostEvaluate() is typically used within time stepping implementations,
3495   most users would not generally call this routine themselves.
3496 
3497   Level: developer
3498 
3499 .keywords: TS, timestep
3500 .seealso: TSSetPostEvaluate(), TSSetPreStep(), TSPreStep(), TSPostStep()
3501 @*/
3502 PetscErrorCode  TSPostEvaluate(TS ts)
3503 {
3504   PetscErrorCode ierr;
3505 
3506   PetscFunctionBegin;
3507   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
3508   if (ts->postevaluate) {
3509     PetscStackCallStandard((*ts->postevaluate),(ts));
3510   }
3511   PetscFunctionReturn(0);
3512 }
3513 
3514 #undef __FUNCT__
3515 #define __FUNCT__ "TSSetPostStep"
3516 /*@C
3517   TSSetPostStep - Sets the general-purpose function
3518   called once at the end of each time step.
3519 
3520   Logically Collective on TS
3521 
3522   Input Parameters:
3523 + ts   - The TS context obtained from TSCreate()
3524 - func - The function
3525 
3526   Calling sequence of func:
3527 $ func (TS ts);
3528 
3529   Notes:
3530   The function set by TSSetPostStep() is called after each successful step. The solution vector X
3531   obtained by TSGetSolution() may be different than that computed at the step end if the event handler
3532   locates an event and TSPostEvent() modifies it. Use TSSetPostEvaluate() if an unmodified solution is needed instead.
3533 
3534   Level: intermediate
3535 
3536 .keywords: TS, timestep
3537 .seealso: TSSetPreStep(), TSSetPreStage(), TSSetPostEvaluate(), TSGetTimeStep(), TSGetTimeStepNumber(), TSGetTime()
3538 @*/
3539 PetscErrorCode  TSSetPostStep(TS ts, PetscErrorCode (*func)(TS))
3540 {
3541   PetscFunctionBegin;
3542   PetscValidHeaderSpecific(ts, TS_CLASSID,1);
3543   ts->poststep = func;
3544   PetscFunctionReturn(0);
3545 }
3546 
3547 #undef __FUNCT__
3548 #define __FUNCT__ "TSPostStep"
3549 /*@
3550   TSPostStep - Runs the user-defined post-step function.
3551 
3552   Collective on TS
3553 
3554   Input Parameters:
3555 . ts   - The TS context obtained from TSCreate()
3556 
3557   Notes:
3558   TSPostStep() is typically used within time stepping implementations,
3559   so most users would not generally call this routine themselves.
3560 
3561   Level: developer
3562 
3563 .keywords: TS, timestep
3564 @*/
3565 PetscErrorCode  TSPostStep(TS ts)
3566 {
3567   PetscErrorCode ierr;
3568 
3569   PetscFunctionBegin;
3570   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
3571   if (ts->poststep) {
3572     PetscStackCallStandard((*ts->poststep),(ts));
3573   }
3574   PetscFunctionReturn(0);
3575 }
3576 
3577 /* ------------ Routines to set performance monitoring options ----------- */
3578 
3579 #undef __FUNCT__
3580 #define __FUNCT__ "TSMonitorSet"
3581 /*@C
3582    TSMonitorSet - Sets an ADDITIONAL function that is to be used at every
3583    timestep to display the iteration's  progress.
3584 
3585    Logically Collective on TS
3586 
3587    Input Parameters:
3588 +  ts - the TS context obtained from TSCreate()
3589 .  monitor - monitoring routine
3590 .  mctx - [optional] user-defined context for private data for the
3591              monitor routine (use NULL if no context is desired)
3592 -  monitordestroy - [optional] routine that frees monitor context
3593           (may be NULL)
3594 
3595    Calling sequence of monitor:
3596 $    int monitor(TS ts,PetscInt steps,PetscReal time,Vec u,void *mctx)
3597 
3598 +    ts - the TS context
3599 .    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)
3600 .    time - current time
3601 .    u - current iterate
3602 -    mctx - [optional] monitoring context
3603 
3604    Notes:
3605    This routine adds an additional monitor to the list of monitors that
3606    already has been loaded.
3607 
3608    Fortran notes: Only a single monitor function can be set for each TS object
3609 
3610    Level: intermediate
3611 
3612 .keywords: TS, timestep, set, monitor
3613 
3614 .seealso: TSMonitorDefault(), TSMonitorCancel()
3615 @*/
3616 PetscErrorCode  TSMonitorSet(TS ts,PetscErrorCode (*monitor)(TS,PetscInt,PetscReal,Vec,void*),void *mctx,PetscErrorCode (*mdestroy)(void**))
3617 {
3618   PetscErrorCode ierr;
3619   PetscInt       i;
3620   PetscBool      identical;
3621 
3622   PetscFunctionBegin;
3623   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
3624   for (i=0; i<ts->numbermonitors;i++) {
3625     ierr = PetscMonitorCompare((PetscErrorCode (*)(void))monitor,mctx,mdestroy,(PetscErrorCode (*)(void))ts->monitor[i],ts->monitorcontext[i],ts->monitordestroy[i],&identical);CHKERRQ(ierr);
3626     if (identical) PetscFunctionReturn(0);
3627   }
3628   if (ts->numbermonitors >= MAXTSMONITORS) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Too many monitors set");
3629   ts->monitor[ts->numbermonitors]          = monitor;
3630   ts->monitordestroy[ts->numbermonitors]   = mdestroy;
3631   ts->monitorcontext[ts->numbermonitors++] = (void*)mctx;
3632   PetscFunctionReturn(0);
3633 }
3634 
3635 #undef __FUNCT__
3636 #define __FUNCT__ "TSMonitorCancel"
3637 /*@C
3638    TSMonitorCancel - Clears all the monitors that have been set on a time-step object.
3639 
3640    Logically Collective on TS
3641 
3642    Input Parameters:
3643 .  ts - the TS context obtained from TSCreate()
3644 
3645    Notes:
3646    There is no way to remove a single, specific monitor.
3647 
3648    Level: intermediate
3649 
3650 .keywords: TS, timestep, set, monitor
3651 
3652 .seealso: TSMonitorDefault(), TSMonitorSet()
3653 @*/
3654 PetscErrorCode  TSMonitorCancel(TS ts)
3655 {
3656   PetscErrorCode ierr;
3657   PetscInt       i;
3658 
3659   PetscFunctionBegin;
3660   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
3661   for (i=0; i<ts->numbermonitors; i++) {
3662     if (ts->monitordestroy[i]) {
3663       ierr = (*ts->monitordestroy[i])(&ts->monitorcontext[i]);CHKERRQ(ierr);
3664     }
3665   }
3666   ts->numbermonitors = 0;
3667   PetscFunctionReturn(0);
3668 }
3669 
3670 #undef __FUNCT__
3671 #define __FUNCT__ "TSMonitorDefault"
3672 /*@C
3673    TSMonitorDefault - The Default monitor, prints the timestep and time for each step
3674 
3675    Level: intermediate
3676 
3677 .keywords: TS, set, monitor
3678 
3679 .seealso:  TSMonitorSet()
3680 @*/
3681 PetscErrorCode TSMonitorDefault(TS ts,PetscInt step,PetscReal ptime,Vec v,PetscViewerAndFormat *vf)
3682 {
3683   PetscErrorCode ierr;
3684   PetscViewer    viewer =  vf->viewer;
3685   PetscBool      iascii,ibinary;
3686 
3687   PetscFunctionBegin;
3688   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,4);
3689   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
3690   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&ibinary);CHKERRQ(ierr);
3691   ierr = PetscViewerPushFormat(viewer,vf->format);CHKERRQ(ierr);
3692   if (iascii) {
3693     ierr = PetscViewerASCIIAddTab(viewer,((PetscObject)ts)->tablevel);CHKERRQ(ierr);
3694     if (step == -1){ /* this indicates it is an interpolated solution */
3695       ierr = PetscViewerASCIIPrintf(viewer,"Interpolated solution at time %g between steps %D and %D\n",(double)ptime,ts->steps-1,ts->steps);CHKERRQ(ierr);
3696     } else {
3697       ierr = PetscViewerASCIIPrintf(viewer,"%D TS dt %g time %g%s",step,(double)ts->time_step,(double)ptime,ts->steprollback ? " (r)\n" : "\n");CHKERRQ(ierr);
3698     }
3699     ierr = PetscViewerASCIISubtractTab(viewer,((PetscObject)ts)->tablevel);CHKERRQ(ierr);
3700   } else if (ibinary) {
3701     PetscMPIInt rank;
3702     ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);CHKERRQ(ierr);
3703     if (!rank) {
3704       PetscBool skipHeader;
3705       PetscInt  classid = REAL_FILE_CLASSID;
3706 
3707       ierr = PetscViewerBinaryGetSkipHeader(viewer,&skipHeader);CHKERRQ(ierr);
3708       if (!skipHeader) {
3709          ierr = PetscViewerBinaryWrite(viewer,&classid,1,PETSC_INT,PETSC_FALSE);CHKERRQ(ierr);
3710        }
3711       ierr = PetscRealView(1,&ptime,viewer);CHKERRQ(ierr);
3712     } else {
3713       ierr = PetscRealView(0,&ptime,viewer);CHKERRQ(ierr);
3714     }
3715   }
3716   ierr = PetscViewerPopFormat(viewer);CHKERRQ(ierr);
3717   PetscFunctionReturn(0);
3718 }
3719 
3720 #undef __FUNCT__
3721 #define __FUNCT__ "TSAdjointMonitorSet"
3722 /*@C
3723    TSAdjointMonitorSet - Sets an ADDITIONAL function that is to be used at every
3724    timestep to display the iteration's  progress.
3725 
3726    Logically Collective on TS
3727 
3728    Input Parameters:
3729 +  ts - the TS context obtained from TSCreate()
3730 .  adjointmonitor - monitoring routine
3731 .  adjointmctx - [optional] user-defined context for private data for the
3732              monitor routine (use NULL if no context is desired)
3733 -  adjointmonitordestroy - [optional] routine that frees monitor context
3734           (may be NULL)
3735 
3736    Calling sequence of monitor:
3737 $    int adjointmonitor(TS ts,PetscInt steps,PetscReal time,Vec u,PetscInt numcost,Vec *lambda, Vec *mu,void *adjointmctx)
3738 
3739 +    ts - the TS context
3740 .    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
3741                                been interpolated to)
3742 .    time - current time
3743 .    u - current iterate
3744 .    numcost - number of cost functionos
3745 .    lambda - sensitivities to initial conditions
3746 .    mu - sensitivities to parameters
3747 -    adjointmctx - [optional] adjoint monitoring context
3748 
3749    Notes:
3750    This routine adds an additional monitor to the list of monitors that
3751    already has been loaded.
3752 
3753    Fortran notes: Only a single monitor function can be set for each TS object
3754 
3755    Level: intermediate
3756 
3757 .keywords: TS, timestep, set, adjoint, monitor
3758 
3759 .seealso: TSAdjointMonitorCancel()
3760 @*/
3761 PetscErrorCode  TSAdjointMonitorSet(TS ts,PetscErrorCode (*adjointmonitor)(TS,PetscInt,PetscReal,Vec,PetscInt,Vec*,Vec*,void*),void *adjointmctx,PetscErrorCode (*adjointmdestroy)(void**))
3762 {
3763   PetscErrorCode ierr;
3764   PetscInt       i;
3765   PetscBool      identical;
3766 
3767   PetscFunctionBegin;
3768   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
3769   for (i=0; i<ts->numbermonitors;i++) {
3770     ierr = PetscMonitorCompare((PetscErrorCode (*)(void))adjointmonitor,adjointmctx,adjointmdestroy,(PetscErrorCode (*)(void))ts->adjointmonitor[i],ts->adjointmonitorcontext[i],ts->adjointmonitordestroy[i],&identical);CHKERRQ(ierr);
3771     if (identical) PetscFunctionReturn(0);
3772   }
3773   if (ts->numberadjointmonitors >= MAXTSMONITORS) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Too many adjoint monitors set");
3774   ts->adjointmonitor[ts->numberadjointmonitors]          = adjointmonitor;
3775   ts->adjointmonitordestroy[ts->numberadjointmonitors]   = adjointmdestroy;
3776   ts->adjointmonitorcontext[ts->numberadjointmonitors++] = (void*)adjointmctx;
3777   PetscFunctionReturn(0);
3778 }
3779 
3780 #undef __FUNCT__
3781 #define __FUNCT__ "TSAdjointMonitorCancel"
3782 /*@C
3783    TSAdjointMonitorCancel - Clears all the adjoint monitors that have been set on a time-step object.
3784 
3785    Logically Collective on TS
3786 
3787    Input Parameters:
3788 .  ts - the TS context obtained from TSCreate()
3789 
3790    Notes:
3791    There is no way to remove a single, specific monitor.
3792 
3793    Level: intermediate
3794 
3795 .keywords: TS, timestep, set, adjoint, monitor
3796 
3797 .seealso: TSAdjointMonitorSet()
3798 @*/
3799 PetscErrorCode  TSAdjointMonitorCancel(TS ts)
3800 {
3801   PetscErrorCode ierr;
3802   PetscInt       i;
3803 
3804   PetscFunctionBegin;
3805   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
3806   for (i=0; i<ts->numberadjointmonitors; i++) {
3807     if (ts->adjointmonitordestroy[i]) {
3808       ierr = (*ts->adjointmonitordestroy[i])(&ts->adjointmonitorcontext[i]);CHKERRQ(ierr);
3809     }
3810   }
3811   ts->numberadjointmonitors = 0;
3812   PetscFunctionReturn(0);
3813 }
3814 
3815 #undef __FUNCT__
3816 #define __FUNCT__ "TSAdjointMonitorDefault"
3817 /*@C
3818    TSAdjointMonitorDefault - the default monitor of adjoint computations
3819 
3820    Level: intermediate
3821 
3822 .keywords: TS, set, monitor
3823 
3824 .seealso: TSAdjointMonitorSet()
3825 @*/
3826 PetscErrorCode TSAdjointMonitorDefault(TS ts,PetscInt step,PetscReal ptime,Vec v,PetscInt numcost,Vec *lambda,Vec *mu,PetscViewerAndFormat *vf)
3827 {
3828   PetscErrorCode ierr;
3829   PetscViewer    viewer = vf->viewer;
3830 
3831   PetscFunctionBegin;
3832   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,4);
3833   ierr = PetscViewerPushFormat(viewer,vf->format);CHKERRQ(ierr);
3834   ierr = PetscViewerASCIIAddTab(viewer,((PetscObject)ts)->tablevel);CHKERRQ(ierr);
3835   ierr = PetscViewerASCIIPrintf(viewer,"%D TS dt %g time %g%s",step,(double)ts->time_step,(double)ptime,ts->steprollback ? " (r)\n" : "\n");CHKERRQ(ierr);
3836   ierr = PetscViewerASCIISubtractTab(viewer,((PetscObject)ts)->tablevel);CHKERRQ(ierr);
3837   ierr = PetscViewerPopFormat(viewer);CHKERRQ(ierr);
3838   PetscFunctionReturn(0);
3839 }
3840 
3841 #undef __FUNCT__
3842 #define __FUNCT__ "TSInterpolate"
3843 /*@
3844    TSInterpolate - Interpolate the solution computed during the previous step to an arbitrary location in the interval
3845 
3846    Collective on TS
3847 
3848    Input Argument:
3849 +  ts - time stepping context
3850 -  t - time to interpolate to
3851 
3852    Output Argument:
3853 .  U - state at given time
3854 
3855    Level: intermediate
3856 
3857    Developer Notes:
3858    TSInterpolate() and the storing of previous steps/stages should be generalized to support delay differential equations and continuous adjoints.
3859 
3860 .keywords: TS, set
3861 
3862 .seealso: TSSetExactFinalTime(), TSSolve()
3863 @*/
3864 PetscErrorCode TSInterpolate(TS ts,PetscReal t,Vec U)
3865 {
3866   PetscErrorCode ierr;
3867 
3868   PetscFunctionBegin;
3869   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
3870   PetscValidHeaderSpecific(U,VEC_CLASSID,3);
3871   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);
3872   if (!ts->ops->interpolate) SETERRQ1(PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"%s does not provide interpolation",((PetscObject)ts)->type_name);
3873   ierr = (*ts->ops->interpolate)(ts,t,U);CHKERRQ(ierr);
3874   PetscFunctionReturn(0);
3875 }
3876 
3877 #undef __FUNCT__
3878 #define __FUNCT__ "TSStep"
3879 /*@
3880    TSStep - Steps one time step
3881 
3882    Collective on TS
3883 
3884    Input Parameter:
3885 .  ts - the TS context obtained from TSCreate()
3886 
3887    Level: developer
3888 
3889    Notes:
3890    The public interface for the ODE/DAE solvers is TSSolve(), you should almost for sure be using that routine and not this routine.
3891 
3892    The hook set using TSSetPreStep() is called before each attempt to take the step. In general, the time step size may
3893    be changed due to adaptive error controller or solve failures. Note that steps may contain multiple stages.
3894 
3895    This may over-step the final time provided in TSSetDuration() depending on the time-step used. TSSolve() interpolates to exactly the
3896    time provided in TSSetDuration(). One can use TSInterpolate() to determine an interpolated solution within the final timestep.
3897 
3898 .keywords: TS, timestep, solve
3899 
3900 .seealso: TSCreate(), TSSetUp(), TSDestroy(), TSSolve(), TSSetPreStep(), TSSetPreStage(), TSSetPostStage(), TSInterpolate()
3901 @*/
3902 PetscErrorCode  TSStep(TS ts)
3903 {
3904   PetscErrorCode   ierr;
3905   static PetscBool cite = PETSC_FALSE;
3906   PetscReal        ptime;
3907 
3908   PetscFunctionBegin;
3909   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
3910   ierr = PetscCitationsRegister("@techreport{tspaper,\n"
3911                                 "  title       = {{PETSc/TS}: A Modern Scalable {DAE/ODE} Solver Library},\n"
3912                                 "  author      = {Shrirang Abhyankar and Jed Brown and Emil Constantinescu and Debojyoti Ghosh and Barry F. Smith},\n"
3913                                 "  type        = {Preprint},\n"
3914                                 "  number      = {ANL/MCS-P5061-0114},\n"
3915                                 "  institution = {Argonne National Laboratory},\n"
3916                                 "  year        = {2014}\n}\n",&cite);CHKERRQ(ierr);
3917 
3918   ierr = TSSetUp(ts);CHKERRQ(ierr);
3919   ierr = TSTrajectorySetUp(ts->trajectory,ts);CHKERRQ(ierr);
3920 
3921   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()");
3922   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");
3923 
3924   if (!ts->steps) ts->ptime_prev = ts->ptime;
3925   ts->reason = TS_CONVERGED_ITERATING;
3926   ptime = ts->ptime; ts->ptime_prev_rollback = ts->ptime_prev;
3927   if (!ts->ops->step) SETERRQ1(PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"TSStep not implemented for type '%s'",((PetscObject)ts)->type_name);
3928   ierr = PetscLogEventBegin(TS_Step,ts,0,0,0);CHKERRQ(ierr);
3929   ierr = (*ts->ops->step)(ts);CHKERRQ(ierr);
3930   ierr = PetscLogEventEnd(TS_Step,ts,0,0,0);CHKERRQ(ierr);
3931   ts->ptime_prev = ptime;
3932   ts->steps++; ts->total_steps++;
3933   ts->steprollback = PETSC_FALSE;
3934   ts->steprestart  = PETSC_FALSE;
3935 
3936   if (ts->reason < 0) {
3937     if (ts->errorifstepfailed) {
3938       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]);
3939       else SETERRQ1(PetscObjectComm((PetscObject)ts),PETSC_ERR_NOT_CONVERGED,"TSStep has failed due to %s",TSConvergedReasons[ts->reason]);
3940     }
3941   } else if (!ts->reason) {
3942     if (ts->steps >= ts->max_steps)     ts->reason = TS_CONVERGED_ITS;
3943     else if (ts->ptime >= ts->max_time) ts->reason = TS_CONVERGED_TIME;
3944   }
3945   PetscFunctionReturn(0);
3946 }
3947 
3948 #undef __FUNCT__
3949 #define __FUNCT__ "TSAdjointStep"
3950 /*@
3951    TSAdjointStep - Steps one time step backward in the adjoint run
3952 
3953    Collective on TS
3954 
3955    Input Parameter:
3956 .  ts - the TS context obtained from TSCreate()
3957 
3958    Level: intermediate
3959 
3960 .keywords: TS, adjoint, step
3961 
3962 .seealso: TSAdjointSetUp(), TSAdjointSolve()
3963 @*/
3964 PetscErrorCode  TSAdjointStep(TS ts)
3965 {
3966   DM               dm;
3967   PetscErrorCode   ierr;
3968 
3969   PetscFunctionBegin;
3970   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
3971   ierr = TSGetDM(ts,&dm);CHKERRQ(ierr);
3972   ierr = TSAdjointSetUp(ts);CHKERRQ(ierr);
3973 
3974   ierr = VecViewFromOptions(ts->vec_sol,(PetscObject)ts,"-ts_view_solution");CHKERRQ(ierr);
3975 
3976   ts->reason = TS_CONVERGED_ITERATING;
3977   ts->ptime_prev = ts->ptime;
3978   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);
3979   ierr = PetscLogEventBegin(TS_AdjointStep,ts,0,0,0);CHKERRQ(ierr);
3980   ierr = (*ts->ops->adjointstep)(ts);CHKERRQ(ierr);
3981   ierr = PetscLogEventEnd(TS_AdjointStep,ts,0,0,0);CHKERRQ(ierr);
3982   ts->steps++; ts->total_steps--;
3983 
3984   if (ts->reason < 0) {
3985     if (ts->errorifstepfailed) {
3986       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]);
3987       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]);
3988       else SETERRQ1(PetscObjectComm((PetscObject)ts),PETSC_ERR_NOT_CONVERGED,"TSStep has failed due to %s",TSConvergedReasons[ts->reason]);
3989     }
3990   } else if (!ts->reason) {
3991     if (ts->steps >= ts->adjoint_max_steps) ts->reason = TS_CONVERGED_ITS;
3992   }
3993   PetscFunctionReturn(0);
3994 }
3995 
3996 #undef __FUNCT__
3997 #define __FUNCT__ "TSEvaluateWLTE"
3998 /*@
3999    TSEvaluateWLTE - Evaluate the weighted local truncation error norm
4000    at the end of a time step with a given order of accuracy.
4001 
4002    Collective on TS
4003 
4004    Input Arguments:
4005 +  ts - time stepping context
4006 .  wnormtype - norm type, either NORM_2 or NORM_INFINITY
4007 -  order - optional, desired order for the error evaluation or PETSC_DECIDE
4008 
4009    Output Arguments:
4010 +  order - optional, the actual order of the error evaluation
4011 -  wlte - the weighted local truncation error norm
4012 
4013    Level: advanced
4014 
4015    Notes:
4016    If the timestepper cannot evaluate the error in a particular step
4017    (eg. in the first step or restart steps after event handling),
4018    this routine returns wlte=-1.0 .
4019 
4020 .seealso: TSStep(), TSAdapt, TSErrorWeightedNorm()
4021 @*/
4022 PetscErrorCode TSEvaluateWLTE(TS ts,NormType wnormtype,PetscInt *order,PetscReal *wlte)
4023 {
4024   PetscErrorCode ierr;
4025 
4026   PetscFunctionBegin;
4027   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
4028   PetscValidType(ts,1);
4029   PetscValidLogicalCollectiveEnum(ts,wnormtype,4);
4030   if (order) PetscValidIntPointer(order,3);
4031   if (order) PetscValidLogicalCollectiveInt(ts,*order,3);
4032   PetscValidRealPointer(wlte,4);
4033   if (wnormtype != NORM_2 && wnormtype != NORM_INFINITY) SETERRQ1(PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"No support for norm type %s",NormTypes[wnormtype]);
4034   if (!ts->ops->evaluatewlte) SETERRQ1(PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"TSEvaluateWLTE not implemented for type '%s'",((PetscObject)ts)->type_name);
4035   ierr = (*ts->ops->evaluatewlte)(ts,wnormtype,order,wlte);CHKERRQ(ierr);
4036   PetscFunctionReturn(0);
4037 }
4038 
4039 #undef __FUNCT__
4040 #define __FUNCT__ "TSEvaluateStep"
4041 /*@
4042    TSEvaluateStep - Evaluate the solution at the end of a time step with a given order of accuracy.
4043 
4044    Collective on TS
4045 
4046    Input Arguments:
4047 +  ts - time stepping context
4048 .  order - desired order of accuracy
4049 -  done - whether the step was evaluated at this order (pass NULL to generate an error if not available)
4050 
4051    Output Arguments:
4052 .  U - state at the end of the current step
4053 
4054    Level: advanced
4055 
4056    Notes:
4057    This function cannot be called until all stages have been evaluated.
4058    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.
4059 
4060 .seealso: TSStep(), TSAdapt
4061 @*/
4062 PetscErrorCode TSEvaluateStep(TS ts,PetscInt order,Vec U,PetscBool *done)
4063 {
4064   PetscErrorCode ierr;
4065 
4066   PetscFunctionBegin;
4067   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
4068   PetscValidType(ts,1);
4069   PetscValidHeaderSpecific(U,VEC_CLASSID,3);
4070   if (!ts->ops->evaluatestep) SETERRQ1(PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"TSEvaluateStep not implemented for type '%s'",((PetscObject)ts)->type_name);
4071   ierr = (*ts->ops->evaluatestep)(ts,order,U,done);CHKERRQ(ierr);
4072   PetscFunctionReturn(0);
4073 }
4074 
4075 #undef __FUNCT__
4076 #define __FUNCT__ "TSForwardCostIntegral"
4077 /*@
4078  TSForwardCostIntegral - Evaluate the cost integral in the forward run.
4079 
4080  Collective on TS
4081 
4082  Input Arguments:
4083  .  ts - time stepping context
4084 
4085  Level: advanced
4086 
4087  Notes:
4088  This function cannot be called until TSStep() has been completed.
4089 
4090  .seealso: TSSolve(), TSAdjointCostIntegral()
4091  @*/
4092 PetscErrorCode TSForwardCostIntegral(TS ts)
4093 {
4094     PetscErrorCode ierr;
4095     PetscValidHeaderSpecific(ts,TS_CLASSID,1);
4096     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);
4097     ierr = (*ts->ops->forwardintegral)(ts);CHKERRQ(ierr);
4098     PetscFunctionReturn(0);
4099 }
4100 
4101 #undef __FUNCT__
4102 #define __FUNCT__ "TSSolve"
4103 /*@
4104    TSSolve - Steps the requested number of timesteps.
4105 
4106    Collective on TS
4107 
4108    Input Parameter:
4109 +  ts - the TS context obtained from TSCreate()
4110 -  u - the solution vector  (can be null if TSSetSolution() was used and TSSetExactFinalTime(ts,TS_EXACTFINALTIME_MATCHSTEP) was not used,
4111                              otherwise must contain the initial conditions and will contain the solution at the final requested time
4112 
4113    Level: beginner
4114 
4115    Notes:
4116    The final time returned by this function may be different from the time of the internally
4117    held state accessible by TSGetSolution() and TSGetTime() because the method may have
4118    stepped over the final time.
4119 
4120 .keywords: TS, timestep, solve
4121 
4122 .seealso: TSCreate(), TSSetSolution(), TSStep(), TSGetTime(), TSGetSolveTime()
4123 @*/
4124 PetscErrorCode TSSolve(TS ts,Vec u)
4125 {
4126   Vec               solution;
4127   PetscErrorCode    ierr;
4128 
4129   PetscFunctionBegin;
4130   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
4131   if (u) PetscValidHeaderSpecific(u,VEC_CLASSID,2);
4132 
4133   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 */
4134     PetscValidHeaderSpecific(u,VEC_CLASSID,2);
4135     if (!ts->vec_sol || u == ts->vec_sol) {
4136       ierr = VecDuplicate(u,&solution);CHKERRQ(ierr);
4137       ierr = TSSetSolution(ts,solution);CHKERRQ(ierr);
4138       ierr = VecDestroy(&solution);CHKERRQ(ierr); /* grant ownership */
4139     }
4140     ierr = VecCopy(u,ts->vec_sol);CHKERRQ(ierr);
4141   } else if (u) {
4142     ierr = TSSetSolution(ts,u);CHKERRQ(ierr);
4143   }
4144   ierr = TSSetUp(ts);CHKERRQ(ierr);
4145   ierr = TSTrajectorySetUp(ts->trajectory,ts);CHKERRQ(ierr);
4146 
4147   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()");
4148   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");
4149 
4150   /* reset time step and iteration counters */
4151   ts->steps             = 0;
4152   ts->ksp_its           = 0;
4153   ts->snes_its          = 0;
4154   ts->num_snes_failures = 0;
4155   ts->reject            = 0;
4156   ts->reason            = TS_CONVERGED_ITERATING;
4157 
4158   ierr = TSViewFromOptions(ts,NULL,"-ts_view_pre");CHKERRQ(ierr);
4159 
4160   if (ts->ops->solve) { /* This private interface is transitional and should be removed when all implementations are updated. */
4161     ierr = (*ts->ops->solve)(ts);CHKERRQ(ierr);
4162     if (u) {ierr = VecCopy(ts->vec_sol,u);CHKERRQ(ierr);}
4163     ts->solvetime = ts->ptime;
4164     solution = ts->vec_sol;
4165   } else { /* Step the requested number of timesteps. */
4166     if (ts->steps >= ts->max_steps)     ts->reason = TS_CONVERGED_ITS;
4167     else if (ts->ptime >= ts->max_time) ts->reason = TS_CONVERGED_TIME;
4168     ierr = TSTrajectorySet(ts->trajectory,ts,ts->steps,ts->ptime,ts->vec_sol);CHKERRQ(ierr);
4169     ierr = TSEventInitialize(ts->event,ts,ts->ptime,ts->vec_sol);CHKERRQ(ierr);
4170     ts->steprollback = PETSC_FALSE;
4171     ts->steprestart  = PETSC_TRUE;
4172 
4173     while (!ts->reason) {
4174       ierr = TSMonitor(ts,ts->steps,ts->ptime,ts->vec_sol);CHKERRQ(ierr);
4175       if (!ts->steprollback) {
4176         ierr = TSPreStep(ts);CHKERRQ(ierr);
4177       }
4178       ierr = TSStep(ts);CHKERRQ(ierr);
4179       if (ts->vec_costintegral && ts->costintegralfwd) { /* Must evaluate the cost integral before event is handled. The cost integral value can also be rolled back. */
4180         ierr = TSForwardCostIntegral(ts);CHKERRQ(ierr);
4181       }
4182       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. */
4183       if (!ts->steprollback) {
4184         ierr = TSTrajectorySet(ts->trajectory,ts,ts->steps,ts->ptime,ts->vec_sol);CHKERRQ(ierr);
4185         ierr = TSPostStep(ts);CHKERRQ(ierr);
4186       }
4187     }
4188     ierr = TSMonitor(ts,ts->steps,ts->ptime,ts->vec_sol);CHKERRQ(ierr);
4189 
4190     if (ts->exact_final_time == TS_EXACTFINALTIME_INTERPOLATE && ts->ptime > ts->max_time) {
4191       ierr = TSInterpolate(ts,ts->max_time,u);CHKERRQ(ierr);
4192       ts->solvetime = ts->max_time;
4193       solution = u;
4194       ierr = TSMonitor(ts,-1,ts->solvetime,solution);CHKERRQ(ierr);
4195     } else {
4196       if (u) {ierr = VecCopy(ts->vec_sol,u);CHKERRQ(ierr);}
4197       ts->solvetime = ts->ptime;
4198       solution = ts->vec_sol;
4199     }
4200   }
4201 
4202   ierr = TSViewFromOptions(ts,NULL,"-ts_view");CHKERRQ(ierr);
4203   ierr = VecViewFromOptions(solution,NULL,"-ts_view_solution");CHKERRQ(ierr);
4204   ierr = PetscObjectSAWsBlock((PetscObject)ts);CHKERRQ(ierr);
4205   if (ts->adjoint_solve) {
4206     ierr = TSAdjointSolve(ts);CHKERRQ(ierr);
4207   }
4208   PetscFunctionReturn(0);
4209 }
4210 
4211 #undef __FUNCT__
4212 #define __FUNCT__ "TSAdjointCostIntegral"
4213 /*@
4214  TSAdjointCostIntegral - Evaluate the cost integral in the adjoint run.
4215 
4216  Collective on TS
4217 
4218  Input Arguments:
4219  .  ts - time stepping context
4220 
4221  Level: advanced
4222 
4223  Notes:
4224  This function cannot be called until TSAdjointStep() has been completed.
4225 
4226  .seealso: TSAdjointSolve(), TSAdjointStep
4227  @*/
4228 PetscErrorCode TSAdjointCostIntegral(TS ts)
4229 {
4230     PetscErrorCode ierr;
4231     PetscValidHeaderSpecific(ts,TS_CLASSID,1);
4232     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);
4233     ierr = (*ts->ops->adjointintegral)(ts);CHKERRQ(ierr);
4234     PetscFunctionReturn(0);
4235 }
4236 
4237 #undef __FUNCT__
4238 #define __FUNCT__ "TSAdjointSolve"
4239 /*@
4240    TSAdjointSolve - Solves the discrete ajoint problem for an ODE/DAE
4241 
4242    Collective on TS
4243 
4244    Input Parameter:
4245 .  ts - the TS context obtained from TSCreate()
4246 
4247    Options Database:
4248 . -ts_adjoint_view_solution <viewerinfo> - views the first gradient with respect to the initial conditions
4249 
4250    Level: intermediate
4251 
4252    Notes:
4253    This must be called after a call to TSSolve() that solves the forward problem
4254 
4255    By default this will integrate back to the initial time, one can use TSAdjointSetSteps() to step back to a later time
4256 
4257 .keywords: TS, timestep, solve
4258 
4259 .seealso: TSCreate(), TSSetCostGradients(), TSSetSolution(), TSAdjointStep()
4260 @*/
4261 PetscErrorCode TSAdjointSolve(TS ts)
4262 {
4263   PetscErrorCode    ierr;
4264 
4265   PetscFunctionBegin;
4266   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
4267   ierr = TSAdjointSetUp(ts);CHKERRQ(ierr);
4268 
4269   /* reset time step and iteration counters */
4270   ts->steps             = 0;
4271   ts->ksp_its           = 0;
4272   ts->snes_its          = 0;
4273   ts->num_snes_failures = 0;
4274   ts->reject            = 0;
4275   ts->reason            = TS_CONVERGED_ITERATING;
4276 
4277   if (!ts->adjoint_max_steps) ts->adjoint_max_steps = ts->total_steps;
4278 
4279   if (ts->steps >= ts->adjoint_max_steps)     ts->reason = TS_CONVERGED_ITS;
4280   while (!ts->reason) {
4281     ierr = TSTrajectoryGet(ts->trajectory,ts,ts->total_steps,&ts->ptime);CHKERRQ(ierr);
4282     ierr = TSAdjointMonitor(ts,ts->total_steps,ts->ptime,ts->vec_sol,ts->numcost,ts->vecs_sensi,ts->vecs_sensip);CHKERRQ(ierr);
4283     ierr = TSAdjointEventHandler(ts);CHKERRQ(ierr);
4284     ierr = TSAdjointStep(ts);CHKERRQ(ierr);
4285     if (ts->vec_costintegral && !ts->costintegralfwd) {
4286       ierr = TSAdjointCostIntegral(ts);CHKERRQ(ierr);
4287     }
4288   }
4289   ierr = TSTrajectoryGet(ts->trajectory,ts,ts->total_steps,&ts->ptime);CHKERRQ(ierr);
4290   ierr = TSAdjointMonitor(ts,ts->total_steps,ts->ptime,ts->vec_sol,ts->numcost,ts->vecs_sensi,ts->vecs_sensip);CHKERRQ(ierr);
4291   ts->solvetime = ts->ptime;
4292   ierr = TSTrajectoryViewFromOptions(ts->trajectory,NULL,"-ts_trajectory_view");CHKERRQ(ierr);
4293   ierr = VecViewFromOptions(ts->vecs_sensi[0],(PetscObject) ts, "-ts_adjoint_view_solution");CHKERRQ(ierr);
4294   PetscFunctionReturn(0);
4295 }
4296 
4297 #undef __FUNCT__
4298 #define __FUNCT__ "TSMonitor"
4299 /*@C
4300    TSMonitor - Runs all user-provided monitor routines set using TSMonitorSet()
4301 
4302    Collective on TS
4303 
4304    Input Parameters:
4305 +  ts - time stepping context obtained from TSCreate()
4306 .  step - step number that has just completed
4307 .  ptime - model time of the state
4308 -  u - state at the current model time
4309 
4310    Notes:
4311    TSMonitor() is typically used automatically within the time stepping implementations.
4312    Users would almost never call this routine directly.
4313 
4314    A step of -1 indicates that the monitor is being called on a solution obtained by interpolating from computed solutions
4315 
4316    Level: developer
4317 
4318 .keywords: TS, timestep
4319 @*/
4320 PetscErrorCode TSMonitor(TS ts,PetscInt step,PetscReal ptime,Vec u)
4321 {
4322   DM             dm;
4323   PetscInt       i,n = ts->numbermonitors;
4324   PetscErrorCode ierr;
4325 
4326   PetscFunctionBegin;
4327   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
4328   PetscValidHeaderSpecific(u,VEC_CLASSID,4);
4329 
4330   ierr = TSGetDM(ts,&dm);CHKERRQ(ierr);
4331   ierr = DMSetOutputSequenceNumber(dm,step,ptime);CHKERRQ(ierr);
4332 
4333   ierr = VecLockPush(u);CHKERRQ(ierr);
4334   for (i=0; i<n; i++) {
4335     ierr = (*ts->monitor[i])(ts,step,ptime,u,ts->monitorcontext[i]);CHKERRQ(ierr);
4336   }
4337   ierr = VecLockPop(u);CHKERRQ(ierr);
4338   PetscFunctionReturn(0);
4339 }
4340 
4341 #undef __FUNCT__
4342 #define __FUNCT__ "TSAdjointMonitor"
4343 /*@C
4344    TSAdjointMonitor - Runs all user-provided adjoint monitor routines set using TSAdjointMonitorSet()
4345 
4346    Collective on TS
4347 
4348    Input Parameters:
4349 +  ts - time stepping context obtained from TSCreate()
4350 .  step - step number that has just completed
4351 .  ptime - model time of the state
4352 .  u - state at the current model time
4353 .  numcost - number of cost functions (dimension of lambda  or mu)
4354 .  lambda - vectors containing the gradients of the cost functions with respect to the ODE/DAE solution variables
4355 -  mu - vectors containing the gradients of the cost functions with respect to the problem parameters
4356 
4357    Notes:
4358    TSAdjointMonitor() is typically used automatically within the time stepping implementations.
4359    Users would almost never call this routine directly.
4360 
4361    Level: developer
4362 
4363 .keywords: TS, timestep
4364 @*/
4365 PetscErrorCode TSAdjointMonitor(TS ts,PetscInt step,PetscReal ptime,Vec u,PetscInt numcost,Vec *lambda, Vec *mu)
4366 {
4367   PetscErrorCode ierr;
4368   PetscInt       i,n = ts->numberadjointmonitors;
4369 
4370   PetscFunctionBegin;
4371   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
4372   PetscValidHeaderSpecific(u,VEC_CLASSID,4);
4373   ierr = VecLockPush(u);CHKERRQ(ierr);
4374   for (i=0; i<n; i++) {
4375     ierr = (*ts->adjointmonitor[i])(ts,step,ptime,u,numcost,lambda,mu,ts->adjointmonitorcontext[i]);CHKERRQ(ierr);
4376   }
4377   ierr = VecLockPop(u);CHKERRQ(ierr);
4378   PetscFunctionReturn(0);
4379 }
4380 
4381 /* ------------------------------------------------------------------------*/
4382 #undef __FUNCT__
4383 #define __FUNCT__ "TSMonitorLGCtxCreate"
4384 /*@C
4385    TSMonitorLGCtxCreate - Creates a TSMonitorLGCtx context for use with
4386    TS to monitor the solution process graphically in various ways
4387 
4388    Collective on TS
4389 
4390    Input Parameters:
4391 +  host - the X display to open, or null for the local machine
4392 .  label - the title to put in the title bar
4393 .  x, y - the screen coordinates of the upper left coordinate of the window
4394 .  m, n - the screen width and height in pixels
4395 -  howoften - if positive then determines the frequency of the plotting, if -1 then only at the final time
4396 
4397    Output Parameter:
4398 .  ctx - the context
4399 
4400    Options Database Key:
4401 +  -ts_monitor_lg_timestep - automatically sets line graph monitor
4402 .  -ts_monitor_lg_solution - monitor the solution (or certain values of the solution by calling TSMonitorLGSetDisplayVariables() or TSMonitorLGCtxSetDisplayVariables())
4403 .  -ts_monitor_lg_error -  monitor the error
4404 .  -ts_monitor_lg_ksp_iterations - monitor the number of KSP iterations needed for each timestep
4405 .  -ts_monitor_lg_snes_iterations - monitor the number of SNES iterations needed for each timestep
4406 -  -lg_use_markers <true,false> - mark the data points (at each time step) on the plot; default is true
4407 
4408    Notes:
4409    Use TSMonitorLGCtxDestroy() to destroy.
4410 
4411    One can provide a function that transforms the solution before plotting it with TSMonitorLGCtxSetTransform() or TSMonitorLGSetTransform()
4412 
4413    Many of the functions that control the monitoring have two forms: TSMonitorLGSet/GetXXXX() and TSMonitorLGCtxSet/GetXXXX() the first take a TS object as the
4414    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
4415    as the first argument.
4416 
4417    One can control the names displayed for each solution or error variable with TSMonitorLGCtxSetVariableNames() or TSMonitorLGSetVariableNames()
4418 
4419 
4420    Level: intermediate
4421 
4422 .keywords: TS, monitor, line graph, residual
4423 
4424 .seealso: TSMonitorLGTimeStep(), TSMonitorSet(), TSMonitorLGSolution(), TSMonitorLGError(), TSMonitorDefault(), VecView(),
4425            TSMonitorLGCtxCreate(), TSMonitorLGCtxSetVariableNames(), TSMonitorLGCtxGetVariableNames(),
4426            TSMonitorLGSetVariableNames(), TSMonitorLGGetVariableNames(), TSMonitorLGSetDisplayVariables(), TSMonitorLGCtxSetDisplayVariables(),
4427            TSMonitorLGCtxSetTransform(), TSMonitorLGSetTransform(), TSMonitorLGError(), TSMonitorLGSNESIterations(), TSMonitorLGKSPIterations(),
4428            TSMonitorEnvelopeCtxCreate(), TSMonitorEnvelopeGetBounds(), TSMonitorEnvelopeCtxDestroy(), TSMonitorEnvelop()
4429 
4430 @*/
4431 PetscErrorCode  TSMonitorLGCtxCreate(MPI_Comm comm,const char host[],const char label[],int x,int y,int m,int n,PetscInt howoften,TSMonitorLGCtx *ctx)
4432 {
4433   PetscDraw      draw;
4434   PetscErrorCode ierr;
4435 
4436   PetscFunctionBegin;
4437   ierr = PetscNew(ctx);CHKERRQ(ierr);
4438   ierr = PetscDrawCreate(comm,host,label,x,y,m,n,&draw);CHKERRQ(ierr);
4439   ierr = PetscDrawSetFromOptions(draw);CHKERRQ(ierr);
4440   ierr = PetscDrawLGCreate(draw,1,&(*ctx)->lg);CHKERRQ(ierr);
4441   ierr = PetscDrawLGSetFromOptions((*ctx)->lg);CHKERRQ(ierr);
4442   ierr = PetscDrawDestroy(&draw);CHKERRQ(ierr);
4443   (*ctx)->howoften = howoften;
4444   PetscFunctionReturn(0);
4445 }
4446 
4447 #undef __FUNCT__
4448 #define __FUNCT__ "TSMonitorLGTimeStep"
4449 PetscErrorCode TSMonitorLGTimeStep(TS ts,PetscInt step,PetscReal ptime,Vec v,void *monctx)
4450 {
4451   TSMonitorLGCtx ctx = (TSMonitorLGCtx) monctx;
4452   PetscReal      x   = ptime,y;
4453   PetscErrorCode ierr;
4454 
4455   PetscFunctionBegin;
4456   if (step < 0) PetscFunctionReturn(0); /* -1 indicates an interpolated solution */
4457   if (!step) {
4458     PetscDrawAxis axis;
4459     ierr = PetscDrawLGGetAxis(ctx->lg,&axis);CHKERRQ(ierr);
4460     ierr = PetscDrawAxisSetLabels(axis,"Timestep as function of time","Time","Time Step");CHKERRQ(ierr);
4461     ierr = PetscDrawLGReset(ctx->lg);CHKERRQ(ierr);
4462   }
4463   ierr = TSGetTimeStep(ts,&y);CHKERRQ(ierr);
4464   ierr = PetscDrawLGAddPoint(ctx->lg,&x,&y);CHKERRQ(ierr);
4465   if (((ctx->howoften > 0) && (!(step % ctx->howoften))) || ((ctx->howoften == -1) && ts->reason)) {
4466     ierr = PetscDrawLGDraw(ctx->lg);CHKERRQ(ierr);
4467     ierr = PetscDrawLGSave(ctx->lg);CHKERRQ(ierr);
4468   }
4469   PetscFunctionReturn(0);
4470 }
4471 
4472 #undef __FUNCT__
4473 #define __FUNCT__ "TSMonitorLGCtxDestroy"
4474 /*@C
4475    TSMonitorLGCtxDestroy - Destroys a line graph context that was created
4476    with TSMonitorLGCtxCreate().
4477 
4478    Collective on TSMonitorLGCtx
4479 
4480    Input Parameter:
4481 .  ctx - the monitor context
4482 
4483    Level: intermediate
4484 
4485 .keywords: TS, monitor, line graph, destroy
4486 
4487 .seealso: TSMonitorLGCtxCreate(),  TSMonitorSet(), TSMonitorLGTimeStep();
4488 @*/
4489 PetscErrorCode  TSMonitorLGCtxDestroy(TSMonitorLGCtx *ctx)
4490 {
4491   PetscErrorCode ierr;
4492 
4493   PetscFunctionBegin;
4494   if ((*ctx)->transformdestroy) {
4495     ierr = ((*ctx)->transformdestroy)((*ctx)->transformctx);CHKERRQ(ierr);
4496   }
4497   ierr = PetscDrawLGDestroy(&(*ctx)->lg);CHKERRQ(ierr);
4498   ierr = PetscStrArrayDestroy(&(*ctx)->names);CHKERRQ(ierr);
4499   ierr = PetscStrArrayDestroy(&(*ctx)->displaynames);CHKERRQ(ierr);
4500   ierr = PetscFree((*ctx)->displayvariables);CHKERRQ(ierr);
4501   ierr = PetscFree((*ctx)->displayvalues);CHKERRQ(ierr);
4502   ierr = PetscFree(*ctx);CHKERRQ(ierr);
4503   PetscFunctionReturn(0);
4504 }
4505 
4506 #undef __FUNCT__
4507 #define __FUNCT__ "TSGetTime"
4508 /*@
4509    TSGetTime - Gets the time of the most recently completed step.
4510 
4511    Not Collective
4512 
4513    Input Parameter:
4514 .  ts - the TS context obtained from TSCreate()
4515 
4516    Output Parameter:
4517 .  t  - the current time. This time may not corresponds to the final time set with TSSetDuration(), use TSGetSolveTime().
4518 
4519    Level: beginner
4520 
4521    Note:
4522    When called during time step evaluation (e.g. during residual evaluation or via hooks set using TSSetPreStep(),
4523    TSSetPreStage(), TSSetPostStage(), or TSSetPostStep()), the time is the time at the start of the step being evaluated.
4524 
4525 .seealso: TSSetInitialTimeStep(), TSGetTimeStep(), TSGetSolveTime()
4526 
4527 .keywords: TS, get, time
4528 @*/
4529 PetscErrorCode  TSGetTime(TS ts,PetscReal *t)
4530 {
4531   PetscFunctionBegin;
4532   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
4533   PetscValidRealPointer(t,2);
4534   *t = ts->ptime;
4535   PetscFunctionReturn(0);
4536 }
4537 
4538 #undef __FUNCT__
4539 #define __FUNCT__ "TSGetPrevTime"
4540 /*@
4541    TSGetPrevTime - Gets the starting time of the previously completed step.
4542 
4543    Not Collective
4544 
4545    Input Parameter:
4546 .  ts - the TS context obtained from TSCreate()
4547 
4548    Output Parameter:
4549 .  t  - the previous time
4550 
4551    Level: beginner
4552 
4553 .seealso: TSSetInitialTimeStep(), TSGetTimeStep()
4554 
4555 .keywords: TS, get, time
4556 @*/
4557 PetscErrorCode  TSGetPrevTime(TS ts,PetscReal *t)
4558 {
4559   PetscFunctionBegin;
4560   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
4561   PetscValidRealPointer(t,2);
4562   *t = ts->ptime_prev;
4563   PetscFunctionReturn(0);
4564 }
4565 
4566 #undef __FUNCT__
4567 #define __FUNCT__ "TSSetTime"
4568 /*@
4569    TSSetTime - Allows one to reset the time.
4570 
4571    Logically Collective on TS
4572 
4573    Input Parameters:
4574 +  ts - the TS context obtained from TSCreate()
4575 -  time - the time
4576 
4577    Level: intermediate
4578 
4579 .seealso: TSGetTime(), TSSetDuration()
4580 
4581 .keywords: TS, set, time
4582 @*/
4583 PetscErrorCode  TSSetTime(TS ts, PetscReal t)
4584 {
4585   PetscFunctionBegin;
4586   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
4587   PetscValidLogicalCollectiveReal(ts,t,2);
4588   ts->ptime = t;
4589   PetscFunctionReturn(0);
4590 }
4591 
4592 #undef __FUNCT__
4593 #define __FUNCT__ "TSSetOptionsPrefix"
4594 /*@C
4595    TSSetOptionsPrefix - Sets the prefix used for searching for all
4596    TS options in the database.
4597 
4598    Logically Collective on TS
4599 
4600    Input Parameter:
4601 +  ts     - The TS context
4602 -  prefix - The prefix to prepend to all option names
4603 
4604    Notes:
4605    A hyphen (-) must NOT be given at the beginning of the prefix name.
4606    The first character of all runtime options is AUTOMATICALLY the
4607    hyphen.
4608 
4609    Level: advanced
4610 
4611 .keywords: TS, set, options, prefix, database
4612 
4613 .seealso: TSSetFromOptions()
4614 
4615 @*/
4616 PetscErrorCode  TSSetOptionsPrefix(TS ts,const char prefix[])
4617 {
4618   PetscErrorCode ierr;
4619   SNES           snes;
4620 
4621   PetscFunctionBegin;
4622   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
4623   ierr = PetscObjectSetOptionsPrefix((PetscObject)ts,prefix);CHKERRQ(ierr);
4624   ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr);
4625   ierr = SNESSetOptionsPrefix(snes,prefix);CHKERRQ(ierr);
4626   PetscFunctionReturn(0);
4627 }
4628 
4629 
4630 #undef __FUNCT__
4631 #define __FUNCT__ "TSAppendOptionsPrefix"
4632 /*@C
4633    TSAppendOptionsPrefix - Appends to the prefix used for searching for all
4634    TS options in the database.
4635 
4636    Logically Collective on TS
4637 
4638    Input Parameter:
4639 +  ts     - The TS context
4640 -  prefix - The prefix to prepend to all option names
4641 
4642    Notes:
4643    A hyphen (-) must NOT be given at the beginning of the prefix name.
4644    The first character of all runtime options is AUTOMATICALLY the
4645    hyphen.
4646 
4647    Level: advanced
4648 
4649 .keywords: TS, append, options, prefix, database
4650 
4651 .seealso: TSGetOptionsPrefix()
4652 
4653 @*/
4654 PetscErrorCode  TSAppendOptionsPrefix(TS ts,const char prefix[])
4655 {
4656   PetscErrorCode ierr;
4657   SNES           snes;
4658 
4659   PetscFunctionBegin;
4660   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
4661   ierr = PetscObjectAppendOptionsPrefix((PetscObject)ts,prefix);CHKERRQ(ierr);
4662   ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr);
4663   ierr = SNESAppendOptionsPrefix(snes,prefix);CHKERRQ(ierr);
4664   PetscFunctionReturn(0);
4665 }
4666 
4667 #undef __FUNCT__
4668 #define __FUNCT__ "TSGetOptionsPrefix"
4669 /*@C
4670    TSGetOptionsPrefix - Sets the prefix used for searching for all
4671    TS options in the database.
4672 
4673    Not Collective
4674 
4675    Input Parameter:
4676 .  ts - The TS context
4677 
4678    Output Parameter:
4679 .  prefix - A pointer to the prefix string used
4680 
4681    Notes: On the fortran side, the user should pass in a string 'prifix' of
4682    sufficient length to hold the prefix.
4683 
4684    Level: intermediate
4685 
4686 .keywords: TS, get, options, prefix, database
4687 
4688 .seealso: TSAppendOptionsPrefix()
4689 @*/
4690 PetscErrorCode  TSGetOptionsPrefix(TS ts,const char *prefix[])
4691 {
4692   PetscErrorCode ierr;
4693 
4694   PetscFunctionBegin;
4695   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
4696   PetscValidPointer(prefix,2);
4697   ierr = PetscObjectGetOptionsPrefix((PetscObject)ts,prefix);CHKERRQ(ierr);
4698   PetscFunctionReturn(0);
4699 }
4700 
4701 #undef __FUNCT__
4702 #define __FUNCT__ "TSGetRHSJacobian"
4703 /*@C
4704    TSGetRHSJacobian - Returns the Jacobian J at the present timestep.
4705 
4706    Not Collective, but parallel objects are returned if TS is parallel
4707 
4708    Input Parameter:
4709 .  ts  - The TS context obtained from TSCreate()
4710 
4711    Output Parameters:
4712 +  Amat - The (approximate) Jacobian J of G, where U_t = G(U,t)  (or NULL)
4713 .  Pmat - The matrix from which the preconditioner is constructed, usually the same as Amat  (or NULL)
4714 .  func - Function to compute the Jacobian of the RHS  (or NULL)
4715 -  ctx - User-defined context for Jacobian evaluation routine  (or NULL)
4716 
4717    Notes: You can pass in NULL for any return argument you do not need.
4718 
4719    Level: intermediate
4720 
4721 .seealso: TSGetTimeStep(), TSGetMatrices(), TSGetTime(), TSGetTimeStepNumber()
4722 
4723 .keywords: TS, timestep, get, matrix, Jacobian
4724 @*/
4725 PetscErrorCode  TSGetRHSJacobian(TS ts,Mat *Amat,Mat *Pmat,TSRHSJacobian *func,void **ctx)
4726 {
4727   PetscErrorCode ierr;
4728   SNES           snes;
4729   DM             dm;
4730 
4731   PetscFunctionBegin;
4732   ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr);
4733   ierr = SNESGetJacobian(snes,Amat,Pmat,NULL,NULL);CHKERRQ(ierr);
4734   ierr = TSGetDM(ts,&dm);CHKERRQ(ierr);
4735   ierr = DMTSGetRHSJacobian(dm,func,ctx);CHKERRQ(ierr);
4736   PetscFunctionReturn(0);
4737 }
4738 
4739 #undef __FUNCT__
4740 #define __FUNCT__ "TSGetIJacobian"
4741 /*@C
4742    TSGetIJacobian - Returns the implicit Jacobian at the present timestep.
4743 
4744    Not Collective, but parallel objects are returned if TS is parallel
4745 
4746    Input Parameter:
4747 .  ts  - The TS context obtained from TSCreate()
4748 
4749    Output Parameters:
4750 +  Amat  - The (approximate) Jacobian of F(t,U,U_t)
4751 .  Pmat - The matrix from which the preconditioner is constructed, often the same as Amat
4752 .  f   - The function to compute the matrices
4753 - ctx - User-defined context for Jacobian evaluation routine
4754 
4755    Notes: You can pass in NULL for any return argument you do not need.
4756 
4757    Level: advanced
4758 
4759 .seealso: TSGetTimeStep(), TSGetRHSJacobian(), TSGetMatrices(), TSGetTime(), TSGetTimeStepNumber()
4760 
4761 .keywords: TS, timestep, get, matrix, Jacobian
4762 @*/
4763 PetscErrorCode  TSGetIJacobian(TS ts,Mat *Amat,Mat *Pmat,TSIJacobian *f,void **ctx)
4764 {
4765   PetscErrorCode ierr;
4766   SNES           snes;
4767   DM             dm;
4768 
4769   PetscFunctionBegin;
4770   ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr);
4771   ierr = SNESSetUpMatrices(snes);CHKERRQ(ierr);
4772   ierr = SNESGetJacobian(snes,Amat,Pmat,NULL,NULL);CHKERRQ(ierr);
4773   ierr = TSGetDM(ts,&dm);CHKERRQ(ierr);
4774   ierr = DMTSGetIJacobian(dm,f,ctx);CHKERRQ(ierr);
4775   PetscFunctionReturn(0);
4776 }
4777 
4778 
4779 #undef __FUNCT__
4780 #define __FUNCT__ "TSMonitorDrawSolution"
4781 /*@C
4782    TSMonitorDrawSolution - Monitors progress of the TS solvers by calling
4783    VecView() for the solution at each timestep
4784 
4785    Collective on TS
4786 
4787    Input Parameters:
4788 +  ts - the TS context
4789 .  step - current time-step
4790 .  ptime - current time
4791 -  dummy - either a viewer or NULL
4792 
4793    Options Database:
4794 .   -ts_monitor_draw_solution_initial - show initial solution as well as current solution
4795 
4796    Notes: the initial solution and current solution are not display with a common axis scaling so generally the option -ts_monitor_draw_solution_initial
4797        will look bad
4798 
4799    Level: intermediate
4800 
4801 .keywords: TS,  vector, monitor, view
4802 
4803 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView()
4804 @*/
4805 PetscErrorCode  TSMonitorDrawSolution(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dummy)
4806 {
4807   PetscErrorCode   ierr;
4808   TSMonitorDrawCtx ictx = (TSMonitorDrawCtx)dummy;
4809   PetscDraw        draw;
4810 
4811   PetscFunctionBegin;
4812   if (!step && ictx->showinitial) {
4813     if (!ictx->initialsolution) {
4814       ierr = VecDuplicate(u,&ictx->initialsolution);CHKERRQ(ierr);
4815     }
4816     ierr = VecCopy(u,ictx->initialsolution);CHKERRQ(ierr);
4817   }
4818   if (!(((ictx->howoften > 0) && (!(step % ictx->howoften))) || ((ictx->howoften == -1) && ts->reason))) PetscFunctionReturn(0);
4819 
4820   if (ictx->showinitial) {
4821     PetscReal pause;
4822     ierr = PetscViewerDrawGetPause(ictx->viewer,&pause);CHKERRQ(ierr);
4823     ierr = PetscViewerDrawSetPause(ictx->viewer,0.0);CHKERRQ(ierr);
4824     ierr = VecView(ictx->initialsolution,ictx->viewer);CHKERRQ(ierr);
4825     ierr = PetscViewerDrawSetPause(ictx->viewer,pause);CHKERRQ(ierr);
4826     ierr = PetscViewerDrawSetHold(ictx->viewer,PETSC_TRUE);CHKERRQ(ierr);
4827   }
4828   ierr = VecView(u,ictx->viewer);CHKERRQ(ierr);
4829   if (ictx->showtimestepandtime) {
4830     PetscReal xl,yl,xr,yr,h;
4831     char      time[32];
4832 
4833     ierr = PetscViewerDrawGetDraw(ictx->viewer,0,&draw);CHKERRQ(ierr);
4834     ierr = PetscSNPrintf(time,32,"Timestep %d Time %g",(int)step,(double)ptime);CHKERRQ(ierr);
4835     ierr = PetscDrawGetCoordinates(draw,&xl,&yl,&xr,&yr);CHKERRQ(ierr);
4836     h    = yl + .95*(yr - yl);
4837     ierr = PetscDrawStringCentered(draw,.5*(xl+xr),h,PETSC_DRAW_BLACK,time);CHKERRQ(ierr);
4838     ierr = PetscDrawFlush(draw);CHKERRQ(ierr);
4839   }
4840 
4841   if (ictx->showinitial) {
4842     ierr = PetscViewerDrawSetHold(ictx->viewer,PETSC_FALSE);CHKERRQ(ierr);
4843   }
4844   PetscFunctionReturn(0);
4845 }
4846 
4847 #undef __FUNCT__
4848 #define __FUNCT__ "TSAdjointMonitorDrawSensi"
4849 /*@C
4850    TSAdjointMonitorDrawSensi - Monitors progress of the adjoint TS solvers by calling
4851    VecView() for the sensitivities to initial states at each timestep
4852 
4853    Collective on TS
4854 
4855    Input Parameters:
4856 +  ts - the TS context
4857 .  step - current time-step
4858 .  ptime - current time
4859 .  u - current state
4860 .  numcost - number of cost functions
4861 .  lambda - sensitivities to initial conditions
4862 .  mu - sensitivities to parameters
4863 -  dummy - either a viewer or NULL
4864 
4865    Level: intermediate
4866 
4867 .keywords: TS,  vector, adjoint, monitor, view
4868 
4869 .seealso: TSAdjointMonitorSet(), TSAdjointMonitorDefault(), VecView()
4870 @*/
4871 PetscErrorCode  TSAdjointMonitorDrawSensi(TS ts,PetscInt step,PetscReal ptime,Vec u,PetscInt numcost,Vec *lambda,Vec *mu,void *dummy)
4872 {
4873   PetscErrorCode   ierr;
4874   TSMonitorDrawCtx ictx = (TSMonitorDrawCtx)dummy;
4875   PetscDraw        draw;
4876   PetscReal        xl,yl,xr,yr,h;
4877   char             time[32];
4878 
4879   PetscFunctionBegin;
4880   if (!(((ictx->howoften > 0) && (!(step % ictx->howoften))) || ((ictx->howoften == -1) && ts->reason))) PetscFunctionReturn(0);
4881 
4882   ierr = VecView(lambda[0],ictx->viewer);CHKERRQ(ierr);
4883   ierr = PetscViewerDrawGetDraw(ictx->viewer,0,&draw);CHKERRQ(ierr);
4884   ierr = PetscSNPrintf(time,32,"Timestep %d Time %g",(int)step,(double)ptime);CHKERRQ(ierr);
4885   ierr = PetscDrawGetCoordinates(draw,&xl,&yl,&xr,&yr);CHKERRQ(ierr);
4886   h    = yl + .95*(yr - yl);
4887   ierr = PetscDrawStringCentered(draw,.5*(xl+xr),h,PETSC_DRAW_BLACK,time);CHKERRQ(ierr);
4888   ierr = PetscDrawFlush(draw);CHKERRQ(ierr);
4889   PetscFunctionReturn(0);
4890 }
4891 
4892 #undef __FUNCT__
4893 #define __FUNCT__ "TSMonitorDrawSolutionPhase"
4894 /*@C
4895    TSMonitorDrawSolutionPhase - Monitors progress of the TS solvers by plotting the solution as a phase diagram
4896 
4897    Collective on TS
4898 
4899    Input Parameters:
4900 +  ts - the TS context
4901 .  step - current time-step
4902 .  ptime - current time
4903 -  dummy - either a viewer or NULL
4904 
4905    Level: intermediate
4906 
4907 .keywords: TS,  vector, monitor, view
4908 
4909 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView()
4910 @*/
4911 PetscErrorCode  TSMonitorDrawSolutionPhase(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dummy)
4912 {
4913   PetscErrorCode    ierr;
4914   TSMonitorDrawCtx  ictx = (TSMonitorDrawCtx)dummy;
4915   PetscDraw         draw;
4916   PetscDrawAxis     axis;
4917   PetscInt          n;
4918   PetscMPIInt       size;
4919   PetscReal         U0,U1,xl,yl,xr,yr,h;
4920   char              time[32];
4921   const PetscScalar *U;
4922 
4923   PetscFunctionBegin;
4924   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)ts),&size);CHKERRQ(ierr);
4925   if (size != 1) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"Only allowed for sequential runs");
4926   ierr = VecGetSize(u,&n);CHKERRQ(ierr);
4927   if (n != 2) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"Only for ODEs with two unknowns");
4928 
4929   ierr = PetscViewerDrawGetDraw(ictx->viewer,0,&draw);CHKERRQ(ierr);
4930   ierr = PetscViewerDrawGetDrawAxis(ictx->viewer,0,&axis);CHKERRQ(ierr);
4931   ierr = PetscDrawAxisGetLimits(axis,&xl,&xr,&yl,&yr);CHKERRQ(ierr);
4932   if (!step) {
4933     ierr = PetscDrawClear(draw);CHKERRQ(ierr);
4934     ierr = PetscDrawAxisDraw(axis);CHKERRQ(ierr);
4935   }
4936 
4937   ierr = VecGetArrayRead(u,&U);CHKERRQ(ierr);
4938   U0 = PetscRealPart(U[0]);
4939   U1 = PetscRealPart(U[1]);
4940   ierr = VecRestoreArrayRead(u,&U);CHKERRQ(ierr);
4941   if ((U0 < xl) || (U1 < yl) || (U0 > xr) || (U1 > yr)) PetscFunctionReturn(0);
4942 
4943   ierr = PetscDrawCollectiveBegin(draw);CHKERRQ(ierr);
4944   ierr = PetscDrawPoint(draw,U0,U1,PETSC_DRAW_BLACK);CHKERRQ(ierr);
4945   if (ictx->showtimestepandtime) {
4946     ierr = PetscDrawGetCoordinates(draw,&xl,&yl,&xr,&yr);CHKERRQ(ierr);
4947     ierr = PetscSNPrintf(time,32,"Timestep %d Time %g",(int)step,(double)ptime);CHKERRQ(ierr);
4948     h    = yl + .95*(yr - yl);
4949     ierr = PetscDrawStringCentered(draw,.5*(xl+xr),h,PETSC_DRAW_BLACK,time);CHKERRQ(ierr);
4950   }
4951   ierr = PetscDrawCollectiveEnd(draw);CHKERRQ(ierr);
4952   ierr = PetscDrawFlush(draw);CHKERRQ(ierr);
4953   ierr = PetscDrawSave(draw);CHKERRQ(ierr);
4954   PetscFunctionReturn(0);
4955 }
4956 
4957 
4958 #undef __FUNCT__
4959 #define __FUNCT__ "TSMonitorDrawCtxDestroy"
4960 /*@C
4961    TSMonitorDrawCtxDestroy - Destroys the monitor context for TSMonitorDrawSolution()
4962 
4963    Collective on TS
4964 
4965    Input Parameters:
4966 .    ctx - the monitor context
4967 
4968    Level: intermediate
4969 
4970 .keywords: TS,  vector, monitor, view
4971 
4972 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorDrawSolution(), TSMonitorDrawError()
4973 @*/
4974 PetscErrorCode  TSMonitorDrawCtxDestroy(TSMonitorDrawCtx *ictx)
4975 {
4976   PetscErrorCode ierr;
4977 
4978   PetscFunctionBegin;
4979   ierr = PetscViewerDestroy(&(*ictx)->viewer);CHKERRQ(ierr);
4980   ierr = VecDestroy(&(*ictx)->initialsolution);CHKERRQ(ierr);
4981   ierr = PetscFree(*ictx);CHKERRQ(ierr);
4982   PetscFunctionReturn(0);
4983 }
4984 
4985 #undef __FUNCT__
4986 #define __FUNCT__ "TSMonitorDrawCtxCreate"
4987 /*@C
4988    TSMonitorDrawCtxCreate - Creates the monitor context for TSMonitorDrawCtx
4989 
4990    Collective on TS
4991 
4992    Input Parameter:
4993 .    ts - time-step context
4994 
4995    Output Patameter:
4996 .    ctx - the monitor context
4997 
4998    Options Database:
4999 .   -ts_monitor_draw_solution_initial - show initial solution as well as current solution
5000 
5001    Level: intermediate
5002 
5003 .keywords: TS,  vector, monitor, view
5004 
5005 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorDrawCtx()
5006 @*/
5007 PetscErrorCode  TSMonitorDrawCtxCreate(MPI_Comm comm,const char host[],const char label[],int x,int y,int m,int n,PetscInt howoften,TSMonitorDrawCtx *ctx)
5008 {
5009   PetscErrorCode   ierr;
5010 
5011   PetscFunctionBegin;
5012   ierr = PetscNew(ctx);CHKERRQ(ierr);
5013   ierr = PetscViewerDrawOpen(comm,host,label,x,y,m,n,&(*ctx)->viewer);CHKERRQ(ierr);
5014   ierr = PetscViewerSetFromOptions((*ctx)->viewer);CHKERRQ(ierr);
5015 
5016   (*ctx)->howoften    = howoften;
5017   (*ctx)->showinitial = PETSC_FALSE;
5018   ierr = PetscOptionsGetBool(NULL,NULL,"-ts_monitor_draw_solution_initial",&(*ctx)->showinitial,NULL);CHKERRQ(ierr);
5019 
5020   (*ctx)->showtimestepandtime = PETSC_FALSE;
5021   ierr = PetscOptionsGetBool(NULL,NULL,"-ts_monitor_draw_solution_show_time",&(*ctx)->showtimestepandtime,NULL);CHKERRQ(ierr);
5022   PetscFunctionReturn(0);
5023 }
5024 
5025 #undef __FUNCT__
5026 #define __FUNCT__ "TSMonitorDrawError"
5027 /*@C
5028    TSMonitorDrawError - Monitors progress of the TS solvers by calling
5029    VecView() for the error at each timestep
5030 
5031    Collective on TS
5032 
5033    Input Parameters:
5034 +  ts - the TS context
5035 .  step - current time-step
5036 .  ptime - current time
5037 -  dummy - either a viewer or NULL
5038 
5039    Level: intermediate
5040 
5041 .keywords: TS,  vector, monitor, view
5042 
5043 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView()
5044 @*/
5045 PetscErrorCode  TSMonitorDrawError(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dummy)
5046 {
5047   PetscErrorCode   ierr;
5048   TSMonitorDrawCtx ctx    = (TSMonitorDrawCtx)dummy;
5049   PetscViewer      viewer = ctx->viewer;
5050   Vec              work;
5051 
5052   PetscFunctionBegin;
5053   if (!(((ctx->howoften > 0) && (!(step % ctx->howoften))) || ((ctx->howoften == -1) && ts->reason))) PetscFunctionReturn(0);
5054   ierr = VecDuplicate(u,&work);CHKERRQ(ierr);
5055   ierr = TSComputeSolutionFunction(ts,ptime,work);CHKERRQ(ierr);
5056   ierr = VecAXPY(work,-1.0,u);CHKERRQ(ierr);
5057   ierr = VecView(work,viewer);CHKERRQ(ierr);
5058   ierr = VecDestroy(&work);CHKERRQ(ierr);
5059   PetscFunctionReturn(0);
5060 }
5061 
5062 #include <petsc/private/dmimpl.h>
5063 #undef __FUNCT__
5064 #define __FUNCT__ "TSSetDM"
5065 /*@
5066    TSSetDM - Sets the DM that may be used by some nonlinear solvers or preconditioners under the TS
5067 
5068    Logically Collective on TS and DM
5069 
5070    Input Parameters:
5071 +  ts - the ODE integrator object
5072 -  dm - the dm, cannot be NULL
5073 
5074    Level: intermediate
5075 
5076 
5077 .seealso: TSGetDM(), SNESSetDM(), SNESGetDM()
5078 @*/
5079 PetscErrorCode  TSSetDM(TS ts,DM dm)
5080 {
5081   PetscErrorCode ierr;
5082   SNES           snes;
5083   DMTS           tsdm;
5084 
5085   PetscFunctionBegin;
5086   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
5087   PetscValidHeaderSpecific(dm,DM_CLASSID,2);
5088   ierr = PetscObjectReference((PetscObject)dm);CHKERRQ(ierr);
5089   if (ts->dm) {               /* Move the DMTS context over to the new DM unless the new DM already has one */
5090     if (ts->dm->dmts && !dm->dmts) {
5091       ierr = DMCopyDMTS(ts->dm,dm);CHKERRQ(ierr);
5092       ierr = DMGetDMTS(ts->dm,&tsdm);CHKERRQ(ierr);
5093       if (tsdm->originaldm == ts->dm) { /* Grant write privileges to the replacement DM */
5094         tsdm->originaldm = dm;
5095       }
5096     }
5097     ierr = DMDestroy(&ts->dm);CHKERRQ(ierr);
5098   }
5099   ts->dm = dm;
5100 
5101   ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr);
5102   ierr = SNESSetDM(snes,dm);CHKERRQ(ierr);
5103   PetscFunctionReturn(0);
5104 }
5105 
5106 #undef __FUNCT__
5107 #define __FUNCT__ "TSGetDM"
5108 /*@
5109    TSGetDM - Gets the DM that may be used by some preconditioners
5110 
5111    Not Collective
5112 
5113    Input Parameter:
5114 . ts - the preconditioner context
5115 
5116    Output Parameter:
5117 .  dm - the dm
5118 
5119    Level: intermediate
5120 
5121 
5122 .seealso: TSSetDM(), SNESSetDM(), SNESGetDM()
5123 @*/
5124 PetscErrorCode  TSGetDM(TS ts,DM *dm)
5125 {
5126   PetscErrorCode ierr;
5127 
5128   PetscFunctionBegin;
5129   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
5130   if (!ts->dm) {
5131     ierr = DMShellCreate(PetscObjectComm((PetscObject)ts),&ts->dm);CHKERRQ(ierr);
5132     if (ts->snes) {ierr = SNESSetDM(ts->snes,ts->dm);CHKERRQ(ierr);}
5133   }
5134   *dm = ts->dm;
5135   PetscFunctionReturn(0);
5136 }
5137 
5138 #undef __FUNCT__
5139 #define __FUNCT__ "SNESTSFormFunction"
5140 /*@
5141    SNESTSFormFunction - Function to evaluate nonlinear residual
5142 
5143    Logically Collective on SNES
5144 
5145    Input Parameter:
5146 + snes - nonlinear solver
5147 . U - the current state at which to evaluate the residual
5148 - ctx - user context, must be a TS
5149 
5150    Output Parameter:
5151 . F - the nonlinear residual
5152 
5153    Notes:
5154    This function is not normally called by users and is automatically registered with the SNES used by TS.
5155    It is most frequently passed to MatFDColoringSetFunction().
5156 
5157    Level: advanced
5158 
5159 .seealso: SNESSetFunction(), MatFDColoringSetFunction()
5160 @*/
5161 PetscErrorCode  SNESTSFormFunction(SNES snes,Vec U,Vec F,void *ctx)
5162 {
5163   TS             ts = (TS)ctx;
5164   PetscErrorCode ierr;
5165 
5166   PetscFunctionBegin;
5167   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
5168   PetscValidHeaderSpecific(U,VEC_CLASSID,2);
5169   PetscValidHeaderSpecific(F,VEC_CLASSID,3);
5170   PetscValidHeaderSpecific(ts,TS_CLASSID,4);
5171   ierr = (ts->ops->snesfunction)(snes,U,F,ts);CHKERRQ(ierr);
5172   PetscFunctionReturn(0);
5173 }
5174 
5175 #undef __FUNCT__
5176 #define __FUNCT__ "SNESTSFormJacobian"
5177 /*@
5178    SNESTSFormJacobian - Function to evaluate the Jacobian
5179 
5180    Collective on SNES
5181 
5182    Input Parameter:
5183 + snes - nonlinear solver
5184 . U - the current state at which to evaluate the residual
5185 - ctx - user context, must be a TS
5186 
5187    Output Parameter:
5188 + A - the Jacobian
5189 . B - the preconditioning matrix (may be the same as A)
5190 - flag - indicates any structure change in the matrix
5191 
5192    Notes:
5193    This function is not normally called by users and is automatically registered with the SNES used by TS.
5194 
5195    Level: developer
5196 
5197 .seealso: SNESSetJacobian()
5198 @*/
5199 PetscErrorCode  SNESTSFormJacobian(SNES snes,Vec U,Mat A,Mat B,void *ctx)
5200 {
5201   TS             ts = (TS)ctx;
5202   PetscErrorCode ierr;
5203 
5204   PetscFunctionBegin;
5205   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
5206   PetscValidHeaderSpecific(U,VEC_CLASSID,2);
5207   PetscValidPointer(A,3);
5208   PetscValidHeaderSpecific(A,MAT_CLASSID,3);
5209   PetscValidPointer(B,4);
5210   PetscValidHeaderSpecific(B,MAT_CLASSID,4);
5211   PetscValidHeaderSpecific(ts,TS_CLASSID,6);
5212   ierr = (ts->ops->snesjacobian)(snes,U,A,B,ts);CHKERRQ(ierr);
5213   PetscFunctionReturn(0);
5214 }
5215 
5216 #undef __FUNCT__
5217 #define __FUNCT__ "TSComputeRHSFunctionLinear"
5218 /*@C
5219    TSComputeRHSFunctionLinear - Evaluate the right hand side via the user-provided Jacobian, for linear problems Udot = A U only
5220 
5221    Collective on TS
5222 
5223    Input Arguments:
5224 +  ts - time stepping context
5225 .  t - time at which to evaluate
5226 .  U - state at which to evaluate
5227 -  ctx - context
5228 
5229    Output Arguments:
5230 .  F - right hand side
5231 
5232    Level: intermediate
5233 
5234    Notes:
5235    This function is intended to be passed to TSSetRHSFunction() to evaluate the right hand side for linear problems.
5236    The matrix (and optionally the evaluation context) should be passed to TSSetRHSJacobian().
5237 
5238 .seealso: TSSetRHSFunction(), TSSetRHSJacobian(), TSComputeRHSJacobianConstant()
5239 @*/
5240 PetscErrorCode TSComputeRHSFunctionLinear(TS ts,PetscReal t,Vec U,Vec F,void *ctx)
5241 {
5242   PetscErrorCode ierr;
5243   Mat            Arhs,Brhs;
5244 
5245   PetscFunctionBegin;
5246   ierr = TSGetRHSMats_Private(ts,&Arhs,&Brhs);CHKERRQ(ierr);
5247   ierr = TSComputeRHSJacobian(ts,t,U,Arhs,Brhs);CHKERRQ(ierr);
5248   ierr = MatMult(Arhs,U,F);CHKERRQ(ierr);
5249   PetscFunctionReturn(0);
5250 }
5251 
5252 #undef __FUNCT__
5253 #define __FUNCT__ "TSComputeRHSJacobianConstant"
5254 /*@C
5255    TSComputeRHSJacobianConstant - Reuses a Jacobian that is time-independent.
5256 
5257    Collective on TS
5258 
5259    Input Arguments:
5260 +  ts - time stepping context
5261 .  t - time at which to evaluate
5262 .  U - state at which to evaluate
5263 -  ctx - context
5264 
5265    Output Arguments:
5266 +  A - pointer to operator
5267 .  B - pointer to preconditioning matrix
5268 -  flg - matrix structure flag
5269 
5270    Level: intermediate
5271 
5272    Notes:
5273    This function is intended to be passed to TSSetRHSJacobian() to evaluate the Jacobian for linear time-independent problems.
5274 
5275 .seealso: TSSetRHSFunction(), TSSetRHSJacobian(), TSComputeRHSFunctionLinear()
5276 @*/
5277 PetscErrorCode TSComputeRHSJacobianConstant(TS ts,PetscReal t,Vec U,Mat A,Mat B,void *ctx)
5278 {
5279   PetscFunctionBegin;
5280   PetscFunctionReturn(0);
5281 }
5282 
5283 #undef __FUNCT__
5284 #define __FUNCT__ "TSComputeIFunctionLinear"
5285 /*@C
5286    TSComputeIFunctionLinear - Evaluate the left hand side via the user-provided Jacobian, for linear problems only
5287 
5288    Collective on TS
5289 
5290    Input Arguments:
5291 +  ts - time stepping context
5292 .  t - time at which to evaluate
5293 .  U - state at which to evaluate
5294 .  Udot - time derivative of state vector
5295 -  ctx - context
5296 
5297    Output Arguments:
5298 .  F - left hand side
5299 
5300    Level: intermediate
5301 
5302    Notes:
5303    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
5304    user is required to write their own TSComputeIFunction.
5305    This function is intended to be passed to TSSetIFunction() to evaluate the left hand side for linear problems.
5306    The matrix (and optionally the evaluation context) should be passed to TSSetIJacobian().
5307 
5308    Note that using this function is NOT equivalent to using TSComputeRHSFunctionLinear() since that solves Udot = A U
5309 
5310 .seealso: TSSetIFunction(), TSSetIJacobian(), TSComputeIJacobianConstant(), TSComputeRHSFunctionLinear()
5311 @*/
5312 PetscErrorCode TSComputeIFunctionLinear(TS ts,PetscReal t,Vec U,Vec Udot,Vec F,void *ctx)
5313 {
5314   PetscErrorCode ierr;
5315   Mat            A,B;
5316 
5317   PetscFunctionBegin;
5318   ierr = TSGetIJacobian(ts,&A,&B,NULL,NULL);CHKERRQ(ierr);
5319   ierr = TSComputeIJacobian(ts,t,U,Udot,1.0,A,B,PETSC_TRUE);CHKERRQ(ierr);
5320   ierr = MatMult(A,Udot,F);CHKERRQ(ierr);
5321   PetscFunctionReturn(0);
5322 }
5323 
5324 #undef __FUNCT__
5325 #define __FUNCT__ "TSComputeIJacobianConstant"
5326 /*@C
5327    TSComputeIJacobianConstant - Reuses a time-independent for a semi-implicit DAE or ODE
5328 
5329    Collective on TS
5330 
5331    Input Arguments:
5332 +  ts - time stepping context
5333 .  t - time at which to evaluate
5334 .  U - state at which to evaluate
5335 .  Udot - time derivative of state vector
5336 .  shift - shift to apply
5337 -  ctx - context
5338 
5339    Output Arguments:
5340 +  A - pointer to operator
5341 .  B - pointer to preconditioning matrix
5342 -  flg - matrix structure flag
5343 
5344    Level: advanced
5345 
5346    Notes:
5347    This function is intended to be passed to TSSetIJacobian() to evaluate the Jacobian for linear time-independent problems.
5348 
5349    It is only appropriate for problems of the form
5350 
5351 $     M Udot = F(U,t)
5352 
5353   where M is constant and F is non-stiff.  The user must pass M to TSSetIJacobian().  The current implementation only
5354   works with IMEX time integration methods such as TSROSW and TSARKIMEX, since there is no support for de-constructing
5355   an implicit operator of the form
5356 
5357 $    shift*M + J
5358 
5359   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
5360   a copy of M or reassemble it when requested.
5361 
5362 .seealso: TSSetIFunction(), TSSetIJacobian(), TSComputeIFunctionLinear()
5363 @*/
5364 PetscErrorCode TSComputeIJacobianConstant(TS ts,PetscReal t,Vec U,Vec Udot,PetscReal shift,Mat A,Mat B,void *ctx)
5365 {
5366   PetscErrorCode ierr;
5367 
5368   PetscFunctionBegin;
5369   ierr = MatScale(A, shift / ts->ijacobian.shift);CHKERRQ(ierr);
5370   ts->ijacobian.shift = shift;
5371   PetscFunctionReturn(0);
5372 }
5373 
5374 #undef __FUNCT__
5375 #define __FUNCT__ "TSGetEquationType"
5376 /*@
5377    TSGetEquationType - Gets the type of the equation that TS is solving.
5378 
5379    Not Collective
5380 
5381    Input Parameter:
5382 .  ts - the TS context
5383 
5384    Output Parameter:
5385 .  equation_type - see TSEquationType
5386 
5387    Level: beginner
5388 
5389 .keywords: TS, equation type
5390 
5391 .seealso: TSSetEquationType(), TSEquationType
5392 @*/
5393 PetscErrorCode  TSGetEquationType(TS ts,TSEquationType *equation_type)
5394 {
5395   PetscFunctionBegin;
5396   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
5397   PetscValidPointer(equation_type,2);
5398   *equation_type = ts->equation_type;
5399   PetscFunctionReturn(0);
5400 }
5401 
5402 #undef __FUNCT__
5403 #define __FUNCT__ "TSSetEquationType"
5404 /*@
5405    TSSetEquationType - Sets the type of the equation that TS is solving.
5406 
5407    Not Collective
5408 
5409    Input Parameter:
5410 +  ts - the TS context
5411 -  equation_type - see TSEquationType
5412 
5413    Level: advanced
5414 
5415 .keywords: TS, equation type
5416 
5417 .seealso: TSGetEquationType(), TSEquationType
5418 @*/
5419 PetscErrorCode  TSSetEquationType(TS ts,TSEquationType equation_type)
5420 {
5421   PetscFunctionBegin;
5422   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
5423   ts->equation_type = equation_type;
5424   PetscFunctionReturn(0);
5425 }
5426 
5427 #undef __FUNCT__
5428 #define __FUNCT__ "TSGetConvergedReason"
5429 /*@
5430    TSGetConvergedReason - Gets the reason the TS iteration was stopped.
5431 
5432    Not Collective
5433 
5434    Input Parameter:
5435 .  ts - the TS context
5436 
5437    Output Parameter:
5438 .  reason - negative value indicates diverged, positive value converged, see TSConvergedReason or the
5439             manual pages for the individual convergence tests for complete lists
5440 
5441    Level: beginner
5442 
5443    Notes:
5444    Can only be called after the call to TSSolve() is complete.
5445 
5446 .keywords: TS, nonlinear, set, convergence, test
5447 
5448 .seealso: TSSetConvergenceTest(), TSConvergedReason
5449 @*/
5450 PetscErrorCode  TSGetConvergedReason(TS ts,TSConvergedReason *reason)
5451 {
5452   PetscFunctionBegin;
5453   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
5454   PetscValidPointer(reason,2);
5455   *reason = ts->reason;
5456   PetscFunctionReturn(0);
5457 }
5458 
5459 #undef __FUNCT__
5460 #define __FUNCT__ "TSSetConvergedReason"
5461 /*@
5462    TSSetConvergedReason - Sets the reason for handling the convergence of TSSolve.
5463 
5464    Not Collective
5465 
5466    Input Parameter:
5467 +  ts - the TS context
5468 .  reason - negative value indicates diverged, positive value converged, see TSConvergedReason or the
5469             manual pages for the individual convergence tests for complete lists
5470 
5471    Level: advanced
5472 
5473    Notes:
5474    Can only be called during TSSolve() is active.
5475 
5476 .keywords: TS, nonlinear, set, convergence, test
5477 
5478 .seealso: TSConvergedReason
5479 @*/
5480 PetscErrorCode  TSSetConvergedReason(TS ts,TSConvergedReason reason)
5481 {
5482   PetscFunctionBegin;
5483   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
5484   ts->reason = reason;
5485   PetscFunctionReturn(0);
5486 }
5487 
5488 #undef __FUNCT__
5489 #define __FUNCT__ "TSGetSolveTime"
5490 /*@
5491    TSGetSolveTime - Gets the time after a call to TSSolve()
5492 
5493    Not Collective
5494 
5495    Input Parameter:
5496 .  ts - the TS context
5497 
5498    Output Parameter:
5499 .  ftime - the final time. This time corresponds to the final time set with TSSetDuration()
5500 
5501    Level: beginner
5502 
5503    Notes:
5504    Can only be called after the call to TSSolve() is complete.
5505 
5506 .keywords: TS, nonlinear, set, convergence, test
5507 
5508 .seealso: TSSetConvergenceTest(), TSConvergedReason
5509 @*/
5510 PetscErrorCode  TSGetSolveTime(TS ts,PetscReal *ftime)
5511 {
5512   PetscFunctionBegin;
5513   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
5514   PetscValidPointer(ftime,2);
5515   *ftime = ts->solvetime;
5516   PetscFunctionReturn(0);
5517 }
5518 
5519 #undef __FUNCT__
5520 #define __FUNCT__ "TSGetTotalSteps"
5521 /*@
5522    TSGetTotalSteps - Gets the total number of steps done since the last call to TSSetUp() or TSCreate()
5523 
5524    Not Collective
5525 
5526    Input Parameter:
5527 .  ts - the TS context
5528 
5529    Output Parameter:
5530 .  steps - the number of steps
5531 
5532    Level: beginner
5533 
5534    Notes:
5535    Includes the number of steps for all calls to TSSolve() since TSSetUp() was called
5536 
5537 .keywords: TS, nonlinear, set, convergence, test
5538 
5539 .seealso: TSSetConvergenceTest(), TSConvergedReason
5540 @*/
5541 PetscErrorCode  TSGetTotalSteps(TS ts,PetscInt *steps)
5542 {
5543   PetscFunctionBegin;
5544   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
5545   PetscValidPointer(steps,2);
5546   *steps = ts->total_steps;
5547   PetscFunctionReturn(0);
5548 }
5549 
5550 #undef __FUNCT__
5551 #define __FUNCT__ "TSGetSNESIterations"
5552 /*@
5553    TSGetSNESIterations - Gets the total number of nonlinear iterations
5554    used by the time integrator.
5555 
5556    Not Collective
5557 
5558    Input Parameter:
5559 .  ts - TS context
5560 
5561    Output Parameter:
5562 .  nits - number of nonlinear iterations
5563 
5564    Notes:
5565    This counter is reset to zero for each successive call to TSSolve().
5566 
5567    Level: intermediate
5568 
5569 .keywords: TS, get, number, nonlinear, iterations
5570 
5571 .seealso:  TSGetKSPIterations()
5572 @*/
5573 PetscErrorCode TSGetSNESIterations(TS ts,PetscInt *nits)
5574 {
5575   PetscFunctionBegin;
5576   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
5577   PetscValidIntPointer(nits,2);
5578   *nits = ts->snes_its;
5579   PetscFunctionReturn(0);
5580 }
5581 
5582 #undef __FUNCT__
5583 #define __FUNCT__ "TSGetKSPIterations"
5584 /*@
5585    TSGetKSPIterations - Gets the total number of linear iterations
5586    used by the time integrator.
5587 
5588    Not Collective
5589 
5590    Input Parameter:
5591 .  ts - TS context
5592 
5593    Output Parameter:
5594 .  lits - number of linear iterations
5595 
5596    Notes:
5597    This counter is reset to zero for each successive call to TSSolve().
5598 
5599    Level: intermediate
5600 
5601 .keywords: TS, get, number, linear, iterations
5602 
5603 .seealso:  TSGetSNESIterations(), SNESGetKSPIterations()
5604 @*/
5605 PetscErrorCode TSGetKSPIterations(TS ts,PetscInt *lits)
5606 {
5607   PetscFunctionBegin;
5608   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
5609   PetscValidIntPointer(lits,2);
5610   *lits = ts->ksp_its;
5611   PetscFunctionReturn(0);
5612 }
5613 
5614 #undef __FUNCT__
5615 #define __FUNCT__ "TSGetStepRejections"
5616 /*@
5617    TSGetStepRejections - Gets the total number of rejected steps.
5618 
5619    Not Collective
5620 
5621    Input Parameter:
5622 .  ts - TS context
5623 
5624    Output Parameter:
5625 .  rejects - number of steps rejected
5626 
5627    Notes:
5628    This counter is reset to zero for each successive call to TSSolve().
5629 
5630    Level: intermediate
5631 
5632 .keywords: TS, get, number
5633 
5634 .seealso:  TSGetSNESIterations(), TSGetKSPIterations(), TSSetMaxStepRejections(), TSGetSNESFailures(), TSSetMaxSNESFailures(), TSSetErrorIfStepFails()
5635 @*/
5636 PetscErrorCode TSGetStepRejections(TS ts,PetscInt *rejects)
5637 {
5638   PetscFunctionBegin;
5639   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
5640   PetscValidIntPointer(rejects,2);
5641   *rejects = ts->reject;
5642   PetscFunctionReturn(0);
5643 }
5644 
5645 #undef __FUNCT__
5646 #define __FUNCT__ "TSGetSNESFailures"
5647 /*@
5648    TSGetSNESFailures - Gets the total number of failed SNES solves
5649 
5650    Not Collective
5651 
5652    Input Parameter:
5653 .  ts - TS context
5654 
5655    Output Parameter:
5656 .  fails - number of failed nonlinear solves
5657 
5658    Notes:
5659    This counter is reset to zero for each successive call to TSSolve().
5660 
5661    Level: intermediate
5662 
5663 .keywords: TS, get, number
5664 
5665 .seealso:  TSGetSNESIterations(), TSGetKSPIterations(), TSSetMaxStepRejections(), TSGetStepRejections(), TSSetMaxSNESFailures()
5666 @*/
5667 PetscErrorCode TSGetSNESFailures(TS ts,PetscInt *fails)
5668 {
5669   PetscFunctionBegin;
5670   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
5671   PetscValidIntPointer(fails,2);
5672   *fails = ts->num_snes_failures;
5673   PetscFunctionReturn(0);
5674 }
5675 
5676 #undef __FUNCT__
5677 #define __FUNCT__ "TSSetMaxStepRejections"
5678 /*@
5679    TSSetMaxStepRejections - Sets the maximum number of step rejections before a step fails
5680 
5681    Not Collective
5682 
5683    Input Parameter:
5684 +  ts - TS context
5685 -  rejects - maximum number of rejected steps, pass -1 for unlimited
5686 
5687    Notes:
5688    The counter is reset to zero for each step
5689 
5690    Options Database Key:
5691  .  -ts_max_reject - Maximum number of step rejections before a step fails
5692 
5693    Level: intermediate
5694 
5695 .keywords: TS, set, maximum, number
5696 
5697 .seealso:  TSGetSNESIterations(), TSGetKSPIterations(), TSSetMaxSNESFailures(), TSGetStepRejections(), TSGetSNESFailures(), TSSetErrorIfStepFails(), TSGetConvergedReason()
5698 @*/
5699 PetscErrorCode TSSetMaxStepRejections(TS ts,PetscInt rejects)
5700 {
5701   PetscFunctionBegin;
5702   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
5703   ts->max_reject = rejects;
5704   PetscFunctionReturn(0);
5705 }
5706 
5707 #undef __FUNCT__
5708 #define __FUNCT__ "TSSetMaxSNESFailures"
5709 /*@
5710    TSSetMaxSNESFailures - Sets the maximum number of failed SNES solves
5711 
5712    Not Collective
5713 
5714    Input Parameter:
5715 +  ts - TS context
5716 -  fails - maximum number of failed nonlinear solves, pass -1 for unlimited
5717 
5718    Notes:
5719    The counter is reset to zero for each successive call to TSSolve().
5720 
5721    Options Database Key:
5722  .  -ts_max_snes_failures - Maximum number of nonlinear solve failures
5723 
5724    Level: intermediate
5725 
5726 .keywords: TS, set, maximum, number
5727 
5728 .seealso:  TSGetSNESIterations(), TSGetKSPIterations(), TSSetMaxStepRejections(), TSGetStepRejections(), TSGetSNESFailures(), SNESGetConvergedReason(), TSGetConvergedReason()
5729 @*/
5730 PetscErrorCode TSSetMaxSNESFailures(TS ts,PetscInt fails)
5731 {
5732   PetscFunctionBegin;
5733   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
5734   ts->max_snes_failures = fails;
5735   PetscFunctionReturn(0);
5736 }
5737 
5738 #undef __FUNCT__
5739 #define __FUNCT__ "TSSetErrorIfStepFails"
5740 /*@
5741    TSSetErrorIfStepFails - Error if no step succeeds
5742 
5743    Not Collective
5744 
5745    Input Parameter:
5746 +  ts - TS context
5747 -  err - PETSC_TRUE to error if no step succeeds, PETSC_FALSE to return without failure
5748 
5749    Options Database Key:
5750  .  -ts_error_if_step_fails - Error if no step succeeds
5751 
5752    Level: intermediate
5753 
5754 .keywords: TS, set, error
5755 
5756 .seealso:  TSGetSNESIterations(), TSGetKSPIterations(), TSSetMaxStepRejections(), TSGetStepRejections(), TSGetSNESFailures(), TSSetErrorIfStepFails(), TSGetConvergedReason()
5757 @*/
5758 PetscErrorCode TSSetErrorIfStepFails(TS ts,PetscBool err)
5759 {
5760   PetscFunctionBegin;
5761   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
5762   ts->errorifstepfailed = err;
5763   PetscFunctionReturn(0);
5764 }
5765 
5766 #undef __FUNCT__
5767 #define __FUNCT__ "TSMonitorSolution"
5768 /*@C
5769    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
5770 
5771    Collective on TS
5772 
5773    Input Parameters:
5774 +  ts - the TS context
5775 .  step - current time-step
5776 .  ptime - current time
5777 .  u - current state
5778 -  vf - viewer and its format
5779 
5780    Level: intermediate
5781 
5782 .keywords: TS,  vector, monitor, view
5783 
5784 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView()
5785 @*/
5786 PetscErrorCode  TSMonitorSolution(TS ts,PetscInt step,PetscReal ptime,Vec u,PetscViewerAndFormat *vf)
5787 {
5788   PetscErrorCode ierr;
5789 
5790   PetscFunctionBegin;
5791   ierr = PetscViewerPushFormat(vf->viewer,vf->format);CHKERRQ(ierr);
5792   ierr = VecView(u,vf->viewer);CHKERRQ(ierr);
5793   ierr = PetscViewerPopFormat(vf->viewer);CHKERRQ(ierr);
5794   PetscFunctionReturn(0);
5795 }
5796 
5797 #undef __FUNCT__
5798 #define __FUNCT__ "TSMonitorSolutionVTK"
5799 /*@C
5800    TSMonitorSolutionVTK - Monitors progress of the TS solvers by VecView() for the solution at each timestep.
5801 
5802    Collective on TS
5803 
5804    Input Parameters:
5805 +  ts - the TS context
5806 .  step - current time-step
5807 .  ptime - current time
5808 .  u - current state
5809 -  filenametemplate - string containing a format specifier for the integer time step (e.g. %03D)
5810 
5811    Level: intermediate
5812 
5813    Notes:
5814    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.
5815    These are named according to the file name template.
5816 
5817    This function is normally passed as an argument to TSMonitorSet() along with TSMonitorSolutionVTKDestroy().
5818 
5819 .keywords: TS,  vector, monitor, view
5820 
5821 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView()
5822 @*/
5823 PetscErrorCode TSMonitorSolutionVTK(TS ts,PetscInt step,PetscReal ptime,Vec u,void *filenametemplate)
5824 {
5825   PetscErrorCode ierr;
5826   char           filename[PETSC_MAX_PATH_LEN];
5827   PetscViewer    viewer;
5828 
5829   PetscFunctionBegin;
5830   if (step < 0) PetscFunctionReturn(0); /* -1 indicates interpolated solution */
5831   ierr = PetscSNPrintf(filename,sizeof(filename),(const char*)filenametemplate,step);CHKERRQ(ierr);
5832   ierr = PetscViewerVTKOpen(PetscObjectComm((PetscObject)ts),filename,FILE_MODE_WRITE,&viewer);CHKERRQ(ierr);
5833   ierr = VecView(u,viewer);CHKERRQ(ierr);
5834   ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr);
5835   PetscFunctionReturn(0);
5836 }
5837 
5838 #undef __FUNCT__
5839 #define __FUNCT__ "TSMonitorSolutionVTKDestroy"
5840 /*@C
5841    TSMonitorSolutionVTKDestroy - Destroy context for monitoring
5842 
5843    Collective on TS
5844 
5845    Input Parameters:
5846 .  filenametemplate - string containing a format specifier for the integer time step (e.g. %03D)
5847 
5848    Level: intermediate
5849 
5850    Note:
5851    This function is normally passed to TSMonitorSet() along with TSMonitorSolutionVTK().
5852 
5853 .keywords: TS,  vector, monitor, view
5854 
5855 .seealso: TSMonitorSet(), TSMonitorSolutionVTK()
5856 @*/
5857 PetscErrorCode TSMonitorSolutionVTKDestroy(void *filenametemplate)
5858 {
5859   PetscErrorCode ierr;
5860 
5861   PetscFunctionBegin;
5862   ierr = PetscFree(*(char**)filenametemplate);CHKERRQ(ierr);
5863   PetscFunctionReturn(0);
5864 }
5865 
5866 #undef __FUNCT__
5867 #define __FUNCT__ "TSGetAdapt"
5868 /*@
5869    TSGetAdapt - Get the adaptive controller context for the current method
5870 
5871    Collective on TS if controller has not been created yet
5872 
5873    Input Arguments:
5874 .  ts - time stepping context
5875 
5876    Output Arguments:
5877 .  adapt - adaptive controller
5878 
5879    Level: intermediate
5880 
5881 .seealso: TSAdapt, TSAdaptSetType(), TSAdaptChoose()
5882 @*/
5883 PetscErrorCode TSGetAdapt(TS ts,TSAdapt *adapt)
5884 {
5885   PetscErrorCode ierr;
5886 
5887   PetscFunctionBegin;
5888   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
5889   PetscValidPointer(adapt,2);
5890   if (!ts->adapt) {
5891     ierr = TSAdaptCreate(PetscObjectComm((PetscObject)ts),&ts->adapt);CHKERRQ(ierr);
5892     ierr = PetscLogObjectParent((PetscObject)ts,(PetscObject)ts->adapt);CHKERRQ(ierr);
5893     ierr = PetscObjectIncrementTabLevel((PetscObject)ts->adapt,(PetscObject)ts,1);CHKERRQ(ierr);
5894   }
5895   *adapt = ts->adapt;
5896   PetscFunctionReturn(0);
5897 }
5898 
5899 #undef __FUNCT__
5900 #define __FUNCT__ "TSSetTolerances"
5901 /*@
5902    TSSetTolerances - Set tolerances for local truncation error when using adaptive controller
5903 
5904    Logically Collective
5905 
5906    Input Arguments:
5907 +  ts - time integration context
5908 .  atol - scalar absolute tolerances, PETSC_DECIDE to leave current value
5909 .  vatol - vector of absolute tolerances or NULL, used in preference to atol if present
5910 .  rtol - scalar relative tolerances, PETSC_DECIDE to leave current value
5911 -  vrtol - vector of relative tolerances or NULL, used in preference to atol if present
5912 
5913    Options Database keys:
5914 +  -ts_rtol <rtol> - relative tolerance for local truncation error
5915 -  -ts_atol <atol> Absolute tolerance for local truncation error
5916 
5917    Notes:
5918    With PETSc's implicit schemes for DAE problems, the calculation of the local truncation error
5919    (LTE) includes both the differential and the algebraic variables. If one wants the LTE to be
5920    computed only for the differential or the algebraic part then this can be done using the vector of
5921    tolerances vatol. For example, by setting the tolerance vector with the desired tolerance for the
5922    differential part and infinity for the algebraic part, the LTE calculation will include only the
5923    differential variables.
5924 
5925    Level: beginner
5926 
5927 .seealso: TS, TSAdapt, TSVecNormWRMS(), TSGetTolerances()
5928 @*/
5929 PetscErrorCode TSSetTolerances(TS ts,PetscReal atol,Vec vatol,PetscReal rtol,Vec vrtol)
5930 {
5931   PetscErrorCode ierr;
5932 
5933   PetscFunctionBegin;
5934   if (atol != PETSC_DECIDE && atol != PETSC_DEFAULT) ts->atol = atol;
5935   if (vatol) {
5936     ierr = PetscObjectReference((PetscObject)vatol);CHKERRQ(ierr);
5937     ierr = VecDestroy(&ts->vatol);CHKERRQ(ierr);
5938     ts->vatol = vatol;
5939   }
5940   if (rtol != PETSC_DECIDE && rtol != PETSC_DEFAULT) ts->rtol = rtol;
5941   if (vrtol) {
5942     ierr = PetscObjectReference((PetscObject)vrtol);CHKERRQ(ierr);
5943     ierr = VecDestroy(&ts->vrtol);CHKERRQ(ierr);
5944     ts->vrtol = vrtol;
5945   }
5946   PetscFunctionReturn(0);
5947 }
5948 
5949 #undef __FUNCT__
5950 #define __FUNCT__ "TSGetTolerances"
5951 /*@
5952    TSGetTolerances - Get tolerances for local truncation error when using adaptive controller
5953 
5954    Logically Collective
5955 
5956    Input Arguments:
5957 .  ts - time integration context
5958 
5959    Output Arguments:
5960 +  atol - scalar absolute tolerances, NULL to ignore
5961 .  vatol - vector of absolute tolerances, NULL to ignore
5962 .  rtol - scalar relative tolerances, NULL to ignore
5963 -  vrtol - vector of relative tolerances, NULL to ignore
5964 
5965    Level: beginner
5966 
5967 .seealso: TS, TSAdapt, TSVecNormWRMS(), TSSetTolerances()
5968 @*/
5969 PetscErrorCode TSGetTolerances(TS ts,PetscReal *atol,Vec *vatol,PetscReal *rtol,Vec *vrtol)
5970 {
5971   PetscFunctionBegin;
5972   if (atol)  *atol  = ts->atol;
5973   if (vatol) *vatol = ts->vatol;
5974   if (rtol)  *rtol  = ts->rtol;
5975   if (vrtol) *vrtol = ts->vrtol;
5976   PetscFunctionReturn(0);
5977 }
5978 
5979 #undef __FUNCT__
5980 #define __FUNCT__ "TSErrorWeightedNorm2"
5981 /*@
5982    TSErrorWeightedNorm2 - compute a weighted 2-norm of the difference between two state vectors
5983 
5984    Collective on TS
5985 
5986    Input Arguments:
5987 +  ts - time stepping context
5988 .  U - state vector, usually ts->vec_sol
5989 -  Y - state vector to be compared to U
5990 
5991    Output Arguments:
5992 .  norm - weighted norm, a value of 1.0 is considered small
5993 
5994    Level: developer
5995 
5996 .seealso: TSErrorWeightedNorm(), TSErrorWeightedNormInfinity()
5997 @*/
5998 PetscErrorCode TSErrorWeightedNorm2(TS ts,Vec U,Vec Y,PetscReal *norm)
5999 {
6000   PetscErrorCode    ierr;
6001   PetscInt          i,n,N,rstart;
6002   const PetscScalar *u,*y;
6003   PetscReal         sum,gsum;
6004   PetscReal         tol;
6005 
6006   PetscFunctionBegin;
6007   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
6008   PetscValidHeaderSpecific(U,VEC_CLASSID,2);
6009   PetscValidHeaderSpecific(Y,VEC_CLASSID,3);
6010   PetscValidType(U,2);
6011   PetscValidType(Y,3);
6012   PetscCheckSameComm(U,2,Y,3);
6013   PetscValidPointer(norm,4);
6014   if (U == Y) SETERRQ(PetscObjectComm((PetscObject)U),PETSC_ERR_ARG_IDN,"U and Y cannot be the same vector");
6015 
6016   ierr = VecGetSize(U,&N);CHKERRQ(ierr);
6017   ierr = VecGetLocalSize(U,&n);CHKERRQ(ierr);
6018   ierr = VecGetOwnershipRange(U,&rstart,NULL);CHKERRQ(ierr);
6019   ierr = VecGetArrayRead(U,&u);CHKERRQ(ierr);
6020   ierr = VecGetArrayRead(Y,&y);CHKERRQ(ierr);
6021   sum  = 0.;
6022   if (ts->vatol && ts->vrtol) {
6023     const PetscScalar *atol,*rtol;
6024     ierr = VecGetArrayRead(ts->vatol,&atol);CHKERRQ(ierr);
6025     ierr = VecGetArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr);
6026     for (i=0; i<n; i++) {
6027       tol = PetscRealPart(atol[i]) + PetscRealPart(rtol[i]) * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i]));
6028       sum += PetscSqr(PetscAbsScalar(y[i] - u[i]) / tol);
6029     }
6030     ierr = VecRestoreArrayRead(ts->vatol,&atol);CHKERRQ(ierr);
6031     ierr = VecRestoreArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr);
6032   } else if (ts->vatol) {       /* vector atol, scalar rtol */
6033     const PetscScalar *atol;
6034     ierr = VecGetArrayRead(ts->vatol,&atol);CHKERRQ(ierr);
6035     for (i=0; i<n; i++) {
6036       tol = PetscRealPart(atol[i]) + ts->rtol * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i]));
6037       sum += PetscSqr(PetscAbsScalar(y[i] - u[i]) / tol);
6038     }
6039     ierr = VecRestoreArrayRead(ts->vatol,&atol);CHKERRQ(ierr);
6040   } else if (ts->vrtol) {       /* scalar atol, vector rtol */
6041     const PetscScalar *rtol;
6042     ierr = VecGetArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr);
6043     for (i=0; i<n; i++) {
6044       tol = ts->atol + PetscRealPart(rtol[i]) * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i]));
6045       sum += PetscSqr(PetscAbsScalar(y[i] - u[i]) / tol);
6046     }
6047     ierr = VecRestoreArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr);
6048   } else {                      /* scalar atol, scalar rtol */
6049     for (i=0; i<n; i++) {
6050       tol = ts->atol + ts->rtol * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i]));
6051       sum += PetscSqr(PetscAbsScalar(y[i] - u[i]) / tol);
6052     }
6053   }
6054   ierr = VecRestoreArrayRead(U,&u);CHKERRQ(ierr);
6055   ierr = VecRestoreArrayRead(Y,&y);CHKERRQ(ierr);
6056 
6057   ierr  = MPIU_Allreduce(&sum,&gsum,1,MPIU_REAL,MPIU_SUM,PetscObjectComm((PetscObject)ts));CHKERRQ(ierr);
6058   *norm = PetscSqrtReal(gsum / N);
6059 
6060   if (PetscIsInfOrNanScalar(*norm)) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_FP,"Infinite or not-a-number generated in norm");
6061   PetscFunctionReturn(0);
6062 }
6063 
6064 #undef __FUNCT__
6065 #define __FUNCT__ "TSErrorWeightedNormInfinity"
6066 /*@
6067    TSErrorWeightedNormInfinity - compute a weighted infinity-norm of the difference between two state vectors
6068 
6069    Collective on TS
6070 
6071    Input Arguments:
6072 +  ts - time stepping context
6073 .  U - state vector, usually ts->vec_sol
6074 -  Y - state vector to be compared to U
6075 
6076    Output Arguments:
6077 .  norm - weighted norm, a value of 1.0 is considered small
6078 
6079    Level: developer
6080 
6081 .seealso: TSErrorWeightedNorm(), TSErrorWeightedNorm2()
6082 @*/
6083 PetscErrorCode TSErrorWeightedNormInfinity(TS ts,Vec U,Vec Y,PetscReal *norm)
6084 {
6085   PetscErrorCode    ierr;
6086   PetscInt          i,n,N,rstart,k;
6087   const PetscScalar *u,*y;
6088   PetscReal         max,gmax;
6089   PetscReal         tol;
6090 
6091   PetscFunctionBegin;
6092   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
6093   PetscValidHeaderSpecific(U,VEC_CLASSID,2);
6094   PetscValidHeaderSpecific(Y,VEC_CLASSID,3);
6095   PetscValidType(U,2);
6096   PetscValidType(Y,3);
6097   PetscCheckSameComm(U,2,Y,3);
6098   PetscValidPointer(norm,4);
6099   if (U == Y) SETERRQ(PetscObjectComm((PetscObject)U),PETSC_ERR_ARG_IDN,"U and Y cannot be the same vector");
6100 
6101   ierr = VecGetSize(U,&N);CHKERRQ(ierr);
6102   ierr = VecGetLocalSize(U,&n);CHKERRQ(ierr);
6103   ierr = VecGetOwnershipRange(U,&rstart,NULL);CHKERRQ(ierr);
6104   ierr = VecGetArrayRead(U,&u);CHKERRQ(ierr);
6105   ierr = VecGetArrayRead(Y,&y);CHKERRQ(ierr);
6106   if (ts->vatol && ts->vrtol) {
6107     const PetscScalar *atol,*rtol;
6108     ierr = VecGetArrayRead(ts->vatol,&atol);CHKERRQ(ierr);
6109     ierr = VecGetArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr);
6110     k = 0;
6111     tol = PetscRealPart(atol[k]) + PetscRealPart(rtol[k]) * PetscMax(PetscAbsScalar(u[k]),PetscAbsScalar(y[k]));
6112     max = PetscAbsScalar(y[k] - u[k]) / tol;
6113     for (i=1; i<n; i++) {
6114       tol = PetscRealPart(atol[i]) + PetscRealPart(rtol[i]) * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i]));
6115       max = PetscMax(max,PetscAbsScalar(y[i] - u[i]) / tol);
6116     }
6117     ierr = VecRestoreArrayRead(ts->vatol,&atol);CHKERRQ(ierr);
6118     ierr = VecRestoreArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr);
6119   } else if (ts->vatol) {       /* vector atol, scalar rtol */
6120     const PetscScalar *atol;
6121     ierr = VecGetArrayRead(ts->vatol,&atol);CHKERRQ(ierr);
6122     k = 0;
6123     tol = PetscRealPart(atol[k]) + ts->rtol * PetscMax(PetscAbsScalar(u[k]),PetscAbsScalar(y[k]));
6124     max = PetscAbsScalar(y[k] - u[k]) / tol;
6125     for (i=1; i<n; i++) {
6126       tol = PetscRealPart(atol[i]) + ts->rtol * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i]));
6127       max = PetscMax(max,PetscAbsScalar(y[i] - u[i]) / tol);
6128     }
6129     ierr = VecRestoreArrayRead(ts->vatol,&atol);CHKERRQ(ierr);
6130   } else if (ts->vrtol) {       /* scalar atol, vector rtol */
6131     const PetscScalar *rtol;
6132     ierr = VecGetArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr);
6133     k = 0;
6134     tol = ts->atol + PetscRealPart(rtol[k]) * PetscMax(PetscAbsScalar(u[k]),PetscAbsScalar(y[k]));
6135     max = PetscAbsScalar(y[k] - u[k]) / tol;
6136     for (i=1; i<n; i++) {
6137       tol = ts->atol + PetscRealPart(rtol[i]) * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i]));
6138       max = PetscMax(max,PetscAbsScalar(y[i] - u[i]) / tol);
6139     }
6140     ierr = VecRestoreArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr);
6141   } else {                      /* scalar atol, scalar rtol */
6142     k = 0;
6143     tol = ts->atol + ts->rtol * PetscMax(PetscAbsScalar(u[k]),PetscAbsScalar(y[k]));
6144     max = PetscAbsScalar(y[k] - u[k]) / tol;
6145     for (i=1; i<n; i++) {
6146       tol = ts->atol + ts->rtol * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i]));
6147       max = PetscMax(max,PetscAbsScalar(y[i] - u[i]) / tol);
6148     }
6149   }
6150   ierr = VecRestoreArrayRead(U,&u);CHKERRQ(ierr);
6151   ierr = VecRestoreArrayRead(Y,&y);CHKERRQ(ierr);
6152 
6153   ierr  = MPIU_Allreduce(&max,&gmax,1,MPIU_REAL,MPIU_MAX,PetscObjectComm((PetscObject)ts));CHKERRQ(ierr);
6154   *norm = gmax;
6155 
6156   if (PetscIsInfOrNanScalar(*norm)) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_FP,"Infinite or not-a-number generated in norm");
6157   PetscFunctionReturn(0);
6158 }
6159 
6160 #undef __FUNCT__
6161 #define __FUNCT__ "TSErrorWeightedNorm"
6162 /*@
6163    TSErrorWeightedNorm - compute a weighted norm of the difference between two state vectors
6164 
6165    Collective on TS
6166 
6167    Input Arguments:
6168 +  ts - time stepping context
6169 .  U - state vector, usually ts->vec_sol
6170 .  Y - state vector to be compared to U
6171 -  wnormtype - norm type, either NORM_2 or NORM_INFINITY
6172 
6173    Output Arguments:
6174 .  norm - weighted norm, a value of 1.0 is considered small
6175 
6176 
6177    Options Database Keys:
6178 .  -ts_adapt_wnormtype <wnormtype> - 2, INFINITY
6179 
6180    Level: developer
6181 
6182 .seealso: TSErrorWeightedNormInfinity(), TSErrorWeightedNorm2()
6183 @*/
6184 PetscErrorCode TSErrorWeightedNorm(TS ts,Vec U,Vec Y,NormType wnormtype,PetscReal *norm)
6185 {
6186   PetscErrorCode ierr;
6187 
6188   PetscFunctionBegin;
6189   if (wnormtype == NORM_2) {
6190     ierr = TSErrorWeightedNorm2(ts,U,Y,norm);CHKERRQ(ierr);
6191   } else if(wnormtype == NORM_INFINITY) {
6192     ierr = TSErrorWeightedNormInfinity(ts,U,Y,norm);CHKERRQ(ierr);
6193   } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"No support for norm type %s",NormTypes[wnormtype]);
6194   PetscFunctionReturn(0);
6195 }
6196 
6197 #undef __FUNCT__
6198 #define __FUNCT__ "TSSetCFLTimeLocal"
6199 /*@
6200    TSSetCFLTimeLocal - Set the local CFL constraint relative to forward Euler
6201 
6202    Logically Collective on TS
6203 
6204    Input Arguments:
6205 +  ts - time stepping context
6206 -  cfltime - maximum stable time step if using forward Euler (value can be different on each process)
6207 
6208    Note:
6209    After calling this function, the global CFL time can be obtained by calling TSGetCFLTime()
6210 
6211    Level: intermediate
6212 
6213 .seealso: TSGetCFLTime(), TSADAPTCFL
6214 @*/
6215 PetscErrorCode TSSetCFLTimeLocal(TS ts,PetscReal cfltime)
6216 {
6217   PetscFunctionBegin;
6218   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
6219   ts->cfltime_local = cfltime;
6220   ts->cfltime       = -1.;
6221   PetscFunctionReturn(0);
6222 }
6223 
6224 #undef __FUNCT__
6225 #define __FUNCT__ "TSGetCFLTime"
6226 /*@
6227    TSGetCFLTime - Get the maximum stable time step according to CFL criteria applied to forward Euler
6228 
6229    Collective on TS
6230 
6231    Input Arguments:
6232 .  ts - time stepping context
6233 
6234    Output Arguments:
6235 .  cfltime - maximum stable time step for forward Euler
6236 
6237    Level: advanced
6238 
6239 .seealso: TSSetCFLTimeLocal()
6240 @*/
6241 PetscErrorCode TSGetCFLTime(TS ts,PetscReal *cfltime)
6242 {
6243   PetscErrorCode ierr;
6244 
6245   PetscFunctionBegin;
6246   if (ts->cfltime < 0) {
6247     ierr = MPIU_Allreduce(&ts->cfltime_local,&ts->cfltime,1,MPIU_REAL,MPIU_MIN,PetscObjectComm((PetscObject)ts));CHKERRQ(ierr);
6248   }
6249   *cfltime = ts->cfltime;
6250   PetscFunctionReturn(0);
6251 }
6252 
6253 #undef __FUNCT__
6254 #define __FUNCT__ "TSVISetVariableBounds"
6255 /*@
6256    TSVISetVariableBounds - Sets the lower and upper bounds for the solution vector. xl <= x <= xu
6257 
6258    Input Parameters:
6259 .  ts   - the TS context.
6260 .  xl   - lower bound.
6261 .  xu   - upper bound.
6262 
6263    Notes:
6264    If this routine is not called then the lower and upper bounds are set to
6265    PETSC_NINFINITY and PETSC_INFINITY respectively during SNESSetUp().
6266 
6267    Level: advanced
6268 
6269 @*/
6270 PetscErrorCode TSVISetVariableBounds(TS ts, Vec xl, Vec xu)
6271 {
6272   PetscErrorCode ierr;
6273   SNES           snes;
6274 
6275   PetscFunctionBegin;
6276   ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr);
6277   ierr = SNESVISetVariableBounds(snes,xl,xu);CHKERRQ(ierr);
6278   PetscFunctionReturn(0);
6279 }
6280 
6281 #if defined(PETSC_HAVE_MATLAB_ENGINE)
6282 #include <mex.h>
6283 
6284 typedef struct {char *funcname; mxArray *ctx;} TSMatlabContext;
6285 
6286 #undef __FUNCT__
6287 #define __FUNCT__ "TSComputeFunction_Matlab"
6288 /*
6289    TSComputeFunction_Matlab - Calls the function that has been set with
6290                          TSSetFunctionMatlab().
6291 
6292    Collective on TS
6293 
6294    Input Parameters:
6295 +  snes - the TS context
6296 -  u - input vector
6297 
6298    Output Parameter:
6299 .  y - function vector, as set by TSSetFunction()
6300 
6301    Notes:
6302    TSComputeFunction() is typically used within nonlinear solvers
6303    implementations, so most users would not generally call this routine
6304    themselves.
6305 
6306    Level: developer
6307 
6308 .keywords: TS, nonlinear, compute, function
6309 
6310 .seealso: TSSetFunction(), TSGetFunction()
6311 */
6312 PetscErrorCode  TSComputeFunction_Matlab(TS snes,PetscReal time,Vec u,Vec udot,Vec y, void *ctx)
6313 {
6314   PetscErrorCode  ierr;
6315   TSMatlabContext *sctx = (TSMatlabContext*)ctx;
6316   int             nlhs  = 1,nrhs = 7;
6317   mxArray         *plhs[1],*prhs[7];
6318   long long int   lx = 0,lxdot = 0,ly = 0,ls = 0;
6319 
6320   PetscFunctionBegin;
6321   PetscValidHeaderSpecific(snes,TS_CLASSID,1);
6322   PetscValidHeaderSpecific(u,VEC_CLASSID,3);
6323   PetscValidHeaderSpecific(udot,VEC_CLASSID,4);
6324   PetscValidHeaderSpecific(y,VEC_CLASSID,5);
6325   PetscCheckSameComm(snes,1,u,3);
6326   PetscCheckSameComm(snes,1,y,5);
6327 
6328   ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr);
6329   ierr = PetscMemcpy(&lx,&u,sizeof(u));CHKERRQ(ierr);
6330   ierr = PetscMemcpy(&lxdot,&udot,sizeof(udot));CHKERRQ(ierr);
6331   ierr = PetscMemcpy(&ly,&y,sizeof(u));CHKERRQ(ierr);
6332 
6333   prhs[0] =  mxCreateDoubleScalar((double)ls);
6334   prhs[1] =  mxCreateDoubleScalar(time);
6335   prhs[2] =  mxCreateDoubleScalar((double)lx);
6336   prhs[3] =  mxCreateDoubleScalar((double)lxdot);
6337   prhs[4] =  mxCreateDoubleScalar((double)ly);
6338   prhs[5] =  mxCreateString(sctx->funcname);
6339   prhs[6] =  sctx->ctx;
6340   ierr    =  mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscTSComputeFunctionInternal");CHKERRQ(ierr);
6341   ierr    =  mxGetScalar(plhs[0]);CHKERRQ(ierr);
6342   mxDestroyArray(prhs[0]);
6343   mxDestroyArray(prhs[1]);
6344   mxDestroyArray(prhs[2]);
6345   mxDestroyArray(prhs[3]);
6346   mxDestroyArray(prhs[4]);
6347   mxDestroyArray(prhs[5]);
6348   mxDestroyArray(plhs[0]);
6349   PetscFunctionReturn(0);
6350 }
6351 
6352 
6353 #undef __FUNCT__
6354 #define __FUNCT__ "TSSetFunctionMatlab"
6355 /*
6356    TSSetFunctionMatlab - Sets the function evaluation routine and function
6357    vector for use by the TS routines in solving ODEs
6358    equations from MATLAB. Here the function is a string containing the name of a MATLAB function
6359 
6360    Logically Collective on TS
6361 
6362    Input Parameters:
6363 +  ts - the TS context
6364 -  func - function evaluation routine
6365 
6366    Calling sequence of func:
6367 $    func (TS ts,PetscReal time,Vec u,Vec udot,Vec f,void *ctx);
6368 
6369    Level: beginner
6370 
6371 .keywords: TS, nonlinear, set, function
6372 
6373 .seealso: TSGetFunction(), TSComputeFunction(), TSSetJacobian(), TSSetFunction()
6374 */
6375 PetscErrorCode  TSSetFunctionMatlab(TS ts,const char *func,mxArray *ctx)
6376 {
6377   PetscErrorCode  ierr;
6378   TSMatlabContext *sctx;
6379 
6380   PetscFunctionBegin;
6381   /* currently sctx is memory bleed */
6382   ierr = PetscNew(&sctx);CHKERRQ(ierr);
6383   ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr);
6384   /*
6385      This should work, but it doesn't
6386   sctx->ctx = ctx;
6387   mexMakeArrayPersistent(sctx->ctx);
6388   */
6389   sctx->ctx = mxDuplicateArray(ctx);
6390 
6391   ierr = TSSetIFunction(ts,NULL,TSComputeFunction_Matlab,sctx);CHKERRQ(ierr);
6392   PetscFunctionReturn(0);
6393 }
6394 
6395 #undef __FUNCT__
6396 #define __FUNCT__ "TSComputeJacobian_Matlab"
6397 /*
6398    TSComputeJacobian_Matlab - Calls the function that has been set with
6399                          TSSetJacobianMatlab().
6400 
6401    Collective on TS
6402 
6403    Input Parameters:
6404 +  ts - the TS context
6405 .  u - input vector
6406 .  A, B - the matrices
6407 -  ctx - user context
6408 
6409    Level: developer
6410 
6411 .keywords: TS, nonlinear, compute, function
6412 
6413 .seealso: TSSetFunction(), TSGetFunction()
6414 @*/
6415 PetscErrorCode  TSComputeJacobian_Matlab(TS ts,PetscReal time,Vec u,Vec udot,PetscReal shift,Mat A,Mat B,void *ctx)
6416 {
6417   PetscErrorCode  ierr;
6418   TSMatlabContext *sctx = (TSMatlabContext*)ctx;
6419   int             nlhs  = 2,nrhs = 9;
6420   mxArray         *plhs[2],*prhs[9];
6421   long long int   lx = 0,lxdot = 0,lA = 0,ls = 0, lB = 0;
6422 
6423   PetscFunctionBegin;
6424   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
6425   PetscValidHeaderSpecific(u,VEC_CLASSID,3);
6426 
6427   /* call Matlab function in ctx with arguments u and y */
6428 
6429   ierr = PetscMemcpy(&ls,&ts,sizeof(ts));CHKERRQ(ierr);
6430   ierr = PetscMemcpy(&lx,&u,sizeof(u));CHKERRQ(ierr);
6431   ierr = PetscMemcpy(&lxdot,&udot,sizeof(u));CHKERRQ(ierr);
6432   ierr = PetscMemcpy(&lA,A,sizeof(u));CHKERRQ(ierr);
6433   ierr = PetscMemcpy(&lB,B,sizeof(u));CHKERRQ(ierr);
6434 
6435   prhs[0] =  mxCreateDoubleScalar((double)ls);
6436   prhs[1] =  mxCreateDoubleScalar((double)time);
6437   prhs[2] =  mxCreateDoubleScalar((double)lx);
6438   prhs[3] =  mxCreateDoubleScalar((double)lxdot);
6439   prhs[4] =  mxCreateDoubleScalar((double)shift);
6440   prhs[5] =  mxCreateDoubleScalar((double)lA);
6441   prhs[6] =  mxCreateDoubleScalar((double)lB);
6442   prhs[7] =  mxCreateString(sctx->funcname);
6443   prhs[8] =  sctx->ctx;
6444   ierr    =  mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscTSComputeJacobianInternal");CHKERRQ(ierr);
6445   ierr    =  mxGetScalar(plhs[0]);CHKERRQ(ierr);
6446   mxDestroyArray(prhs[0]);
6447   mxDestroyArray(prhs[1]);
6448   mxDestroyArray(prhs[2]);
6449   mxDestroyArray(prhs[3]);
6450   mxDestroyArray(prhs[4]);
6451   mxDestroyArray(prhs[5]);
6452   mxDestroyArray(prhs[6]);
6453   mxDestroyArray(prhs[7]);
6454   mxDestroyArray(plhs[0]);
6455   mxDestroyArray(plhs[1]);
6456   PetscFunctionReturn(0);
6457 }
6458 
6459 
6460 #undef __FUNCT__
6461 #define __FUNCT__ "TSSetJacobianMatlab"
6462 /*
6463    TSSetJacobianMatlab - Sets the Jacobian function evaluation routine and two empty Jacobian matrices
6464    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
6465 
6466    Logically Collective on TS
6467 
6468    Input Parameters:
6469 +  ts - the TS context
6470 .  A,B - Jacobian matrices
6471 .  func - function evaluation routine
6472 -  ctx - user context
6473 
6474    Calling sequence of func:
6475 $    flag = func (TS ts,PetscReal time,Vec u,Vec udot,Mat A,Mat B,void *ctx);
6476 
6477 
6478    Level: developer
6479 
6480 .keywords: TS, nonlinear, set, function
6481 
6482 .seealso: TSGetFunction(), TSComputeFunction(), TSSetJacobian(), TSSetFunction()
6483 */
6484 PetscErrorCode  TSSetJacobianMatlab(TS ts,Mat A,Mat B,const char *func,mxArray *ctx)
6485 {
6486   PetscErrorCode  ierr;
6487   TSMatlabContext *sctx;
6488 
6489   PetscFunctionBegin;
6490   /* currently sctx is memory bleed */
6491   ierr = PetscNew(&sctx);CHKERRQ(ierr);
6492   ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr);
6493   /*
6494      This should work, but it doesn't
6495   sctx->ctx = ctx;
6496   mexMakeArrayPersistent(sctx->ctx);
6497   */
6498   sctx->ctx = mxDuplicateArray(ctx);
6499 
6500   ierr = TSSetIJacobian(ts,A,B,TSComputeJacobian_Matlab,sctx);CHKERRQ(ierr);
6501   PetscFunctionReturn(0);
6502 }
6503 
6504 #undef __FUNCT__
6505 #define __FUNCT__ "TSMonitor_Matlab"
6506 /*
6507    TSMonitor_Matlab - Calls the function that has been set with TSMonitorSetMatlab().
6508 
6509    Collective on TS
6510 
6511 .seealso: TSSetFunction(), TSGetFunction()
6512 @*/
6513 PetscErrorCode  TSMonitor_Matlab(TS ts,PetscInt it, PetscReal time,Vec u, void *ctx)
6514 {
6515   PetscErrorCode  ierr;
6516   TSMatlabContext *sctx = (TSMatlabContext*)ctx;
6517   int             nlhs  = 1,nrhs = 6;
6518   mxArray         *plhs[1],*prhs[6];
6519   long long int   lx = 0,ls = 0;
6520 
6521   PetscFunctionBegin;
6522   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
6523   PetscValidHeaderSpecific(u,VEC_CLASSID,4);
6524 
6525   ierr = PetscMemcpy(&ls,&ts,sizeof(ts));CHKERRQ(ierr);
6526   ierr = PetscMemcpy(&lx,&u,sizeof(u));CHKERRQ(ierr);
6527 
6528   prhs[0] =  mxCreateDoubleScalar((double)ls);
6529   prhs[1] =  mxCreateDoubleScalar((double)it);
6530   prhs[2] =  mxCreateDoubleScalar((double)time);
6531   prhs[3] =  mxCreateDoubleScalar((double)lx);
6532   prhs[4] =  mxCreateString(sctx->funcname);
6533   prhs[5] =  sctx->ctx;
6534   ierr    =  mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscTSMonitorInternal");CHKERRQ(ierr);
6535   ierr    =  mxGetScalar(plhs[0]);CHKERRQ(ierr);
6536   mxDestroyArray(prhs[0]);
6537   mxDestroyArray(prhs[1]);
6538   mxDestroyArray(prhs[2]);
6539   mxDestroyArray(prhs[3]);
6540   mxDestroyArray(prhs[4]);
6541   mxDestroyArray(plhs[0]);
6542   PetscFunctionReturn(0);
6543 }
6544 
6545 
6546 #undef __FUNCT__
6547 #define __FUNCT__ "TSMonitorSetMatlab"
6548 /*
6549    TSMonitorSetMatlab - Sets the monitor function from Matlab
6550 
6551    Level: developer
6552 
6553 .keywords: TS, nonlinear, set, function
6554 
6555 .seealso: TSGetFunction(), TSComputeFunction(), TSSetJacobian(), TSSetFunction()
6556 */
6557 PetscErrorCode  TSMonitorSetMatlab(TS ts,const char *func,mxArray *ctx)
6558 {
6559   PetscErrorCode  ierr;
6560   TSMatlabContext *sctx;
6561 
6562   PetscFunctionBegin;
6563   /* currently sctx is memory bleed */
6564   ierr = PetscNew(&sctx);CHKERRQ(ierr);
6565   ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr);
6566   /*
6567      This should work, but it doesn't
6568   sctx->ctx = ctx;
6569   mexMakeArrayPersistent(sctx->ctx);
6570   */
6571   sctx->ctx = mxDuplicateArray(ctx);
6572 
6573   ierr = TSMonitorSet(ts,TSMonitor_Matlab,sctx,NULL);CHKERRQ(ierr);
6574   PetscFunctionReturn(0);
6575 }
6576 #endif
6577 
6578 #undef __FUNCT__
6579 #define __FUNCT__ "TSMonitorLGSolution"
6580 /*@C
6581    TSMonitorLGSolution - Monitors progress of the TS solvers by plotting each component of the solution vector
6582        in a time based line graph
6583 
6584    Collective on TS
6585 
6586    Input Parameters:
6587 +  ts - the TS context
6588 .  step - current time-step
6589 .  ptime - current time
6590 .  u - current solution
6591 -  dctx - the TSMonitorLGCtx object that contains all the options for the monitoring, this is created with TSMonitorLGCtxCreate()
6592 
6593    Options Database:
6594 .   -ts_monitor_lg_solution_variables
6595 
6596    Level: intermediate
6597 
6598    Notes: Each process in a parallel run displays its component solutions in a separate window
6599 
6600 .keywords: TS,  vector, monitor, view
6601 
6602 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorLGCtxCreate(), TSMonitorLGCtxSetVariableNames(), TSMonitorLGCtxGetVariableNames(),
6603            TSMonitorLGSetVariableNames(), TSMonitorLGGetVariableNames(), TSMonitorLGSetDisplayVariables(), TSMonitorLGCtxSetDisplayVariables(),
6604            TSMonitorLGCtxSetTransform(), TSMonitorLGSetTransform(), TSMonitorLGError(), TSMonitorLGSNESIterations(), TSMonitorLGKSPIterations(),
6605            TSMonitorEnvelopeCtxCreate(), TSMonitorEnvelopeGetBounds(), TSMonitorEnvelopeCtxDestroy(), TSMonitorEnvelop()
6606 @*/
6607 PetscErrorCode  TSMonitorLGSolution(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dctx)
6608 {
6609   PetscErrorCode    ierr;
6610   TSMonitorLGCtx    ctx = (TSMonitorLGCtx)dctx;
6611   const PetscScalar *yy;
6612   Vec               v;
6613 
6614   PetscFunctionBegin;
6615   if (step < 0) PetscFunctionReturn(0); /* -1 indicates interpolated solution */
6616   if (!step) {
6617     PetscDrawAxis axis;
6618     PetscInt      dim;
6619     ierr = PetscDrawLGGetAxis(ctx->lg,&axis);CHKERRQ(ierr);
6620     ierr = PetscDrawAxisSetLabels(axis,"Solution as function of time","Time","Solution");CHKERRQ(ierr);
6621     if (!ctx->names) {
6622       PetscBool flg;
6623       /* user provides names of variables to plot but no names has been set so assume names are integer values */
6624       ierr = PetscOptionsHasName(((PetscObject)ts)->options,((PetscObject)ts)->prefix,"-ts_monitor_lg_solution_variables",&flg);CHKERRQ(ierr);
6625       if (flg) {
6626         PetscInt i,n;
6627         char     **names;
6628         ierr = VecGetSize(u,&n);CHKERRQ(ierr);
6629         ierr = PetscMalloc1(n+1,&names);CHKERRQ(ierr);
6630         for (i=0; i<n; i++) {
6631           ierr = PetscMalloc1(5,&names[i]);CHKERRQ(ierr);
6632           ierr = PetscSNPrintf(names[i],5,"%D",i);CHKERRQ(ierr);
6633         }
6634         names[n] = NULL;
6635         ctx->names = names;
6636       }
6637     }
6638     if (ctx->names && !ctx->displaynames) {
6639       char      **displaynames;
6640       PetscBool flg;
6641       ierr = VecGetLocalSize(u,&dim);CHKERRQ(ierr);
6642       ierr = PetscMalloc1(dim+1,&displaynames);CHKERRQ(ierr);
6643       ierr = PetscMemzero(displaynames,(dim+1)*sizeof(char*));CHKERRQ(ierr);
6644       ierr = PetscOptionsGetStringArray(((PetscObject)ts)->options,((PetscObject)ts)->prefix,"-ts_monitor_lg_solution_variables",displaynames,&dim,&flg);CHKERRQ(ierr);
6645       if (flg) {
6646         ierr = TSMonitorLGCtxSetDisplayVariables(ctx,(const char *const *)displaynames);CHKERRQ(ierr);
6647       }
6648       ierr = PetscStrArrayDestroy(&displaynames);CHKERRQ(ierr);
6649     }
6650     if (ctx->displaynames) {
6651       ierr = PetscDrawLGSetDimension(ctx->lg,ctx->ndisplayvariables);CHKERRQ(ierr);
6652       ierr = PetscDrawLGSetLegend(ctx->lg,(const char *const *)ctx->displaynames);CHKERRQ(ierr);
6653     } else if (ctx->names) {
6654       ierr = VecGetLocalSize(u,&dim);CHKERRQ(ierr);
6655       ierr = PetscDrawLGSetDimension(ctx->lg,dim);CHKERRQ(ierr);
6656       ierr = PetscDrawLGSetLegend(ctx->lg,(const char *const *)ctx->names);CHKERRQ(ierr);
6657     } else {
6658       ierr = VecGetLocalSize(u,&dim);CHKERRQ(ierr);
6659       ierr = PetscDrawLGSetDimension(ctx->lg,dim);CHKERRQ(ierr);
6660     }
6661     ierr = PetscDrawLGReset(ctx->lg);CHKERRQ(ierr);
6662   }
6663 
6664   if (!ctx->transform) v = u;
6665   else {ierr = (*ctx->transform)(ctx->transformctx,u,&v);CHKERRQ(ierr);}
6666   ierr = VecGetArrayRead(v,&yy);CHKERRQ(ierr);
6667   if (ctx->displaynames) {
6668     PetscInt i;
6669     for (i=0; i<ctx->ndisplayvariables; i++)
6670       ctx->displayvalues[i] = PetscRealPart(yy[ctx->displayvariables[i]]);
6671     ierr = PetscDrawLGAddCommonPoint(ctx->lg,ptime,ctx->displayvalues);CHKERRQ(ierr);
6672   } else {
6673 #if defined(PETSC_USE_COMPLEX)
6674     PetscInt  i,n;
6675     PetscReal *yreal;
6676     ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr);
6677     ierr = PetscMalloc1(n,&yreal);CHKERRQ(ierr);
6678     for (i=0; i<n; i++) yreal[i] = PetscRealPart(yy[i]);
6679     ierr = PetscDrawLGAddCommonPoint(ctx->lg,ptime,yreal);CHKERRQ(ierr);
6680     ierr = PetscFree(yreal);CHKERRQ(ierr);
6681 #else
6682     ierr = PetscDrawLGAddCommonPoint(ctx->lg,ptime,yy);CHKERRQ(ierr);
6683 #endif
6684   }
6685   ierr = VecRestoreArrayRead(v,&yy);CHKERRQ(ierr);
6686   if (ctx->transform) {ierr = VecDestroy(&v);CHKERRQ(ierr);}
6687 
6688   if (((ctx->howoften > 0) && (!(step % ctx->howoften))) || ((ctx->howoften == -1) && ts->reason)) {
6689     ierr = PetscDrawLGDraw(ctx->lg);CHKERRQ(ierr);
6690     ierr = PetscDrawLGSave(ctx->lg);CHKERRQ(ierr);
6691   }
6692   PetscFunctionReturn(0);
6693 }
6694 
6695 
6696 #undef __FUNCT__
6697 #define __FUNCT__ "TSMonitorLGSetVariableNames"
6698 /*@C
6699    TSMonitorLGSetVariableNames - Sets the name of each component in the solution vector so that it may be displayed in the plot
6700 
6701    Collective on TS
6702 
6703    Input Parameters:
6704 +  ts - the TS context
6705 -  names - the names of the components, final string must be NULL
6706 
6707    Level: intermediate
6708 
6709    Notes: If the TS object does not have a TSMonitorLGCtx associated with it then this function is ignored
6710 
6711 .keywords: TS,  vector, monitor, view
6712 
6713 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorLGSetDisplayVariables(), TSMonitorLGCtxSetVariableNames()
6714 @*/
6715 PetscErrorCode  TSMonitorLGSetVariableNames(TS ts,const char * const *names)
6716 {
6717   PetscErrorCode    ierr;
6718   PetscInt          i;
6719 
6720   PetscFunctionBegin;
6721   for (i=0; i<ts->numbermonitors; i++) {
6722     if (ts->monitor[i] == TSMonitorLGSolution) {
6723       ierr = TSMonitorLGCtxSetVariableNames((TSMonitorLGCtx)ts->monitorcontext[i],names);CHKERRQ(ierr);
6724       break;
6725     }
6726   }
6727   PetscFunctionReturn(0);
6728 }
6729 
6730 #undef __FUNCT__
6731 #define __FUNCT__ "TSMonitorLGCtxSetVariableNames"
6732 /*@C
6733    TSMonitorLGCtxSetVariableNames - Sets the name of each component in the solution vector so that it may be displayed in the plot
6734 
6735    Collective on TS
6736 
6737    Input Parameters:
6738 +  ts - the TS context
6739 -  names - the names of the components, final string must be NULL
6740 
6741    Level: intermediate
6742 
6743 .keywords: TS,  vector, monitor, view
6744 
6745 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorLGSetDisplayVariables(), TSMonitorLGSetVariableNames()
6746 @*/
6747 PetscErrorCode  TSMonitorLGCtxSetVariableNames(TSMonitorLGCtx ctx,const char * const *names)
6748 {
6749   PetscErrorCode    ierr;
6750 
6751   PetscFunctionBegin;
6752   ierr = PetscStrArrayDestroy(&ctx->names);CHKERRQ(ierr);
6753   ierr = PetscStrArrayallocpy(names,&ctx->names);CHKERRQ(ierr);
6754   PetscFunctionReturn(0);
6755 }
6756 
6757 #undef __FUNCT__
6758 #define __FUNCT__ "TSMonitorLGGetVariableNames"
6759 /*@C
6760    TSMonitorLGGetVariableNames - Gets the name of each component in the solution vector so that it may be displayed in the plot
6761 
6762    Collective on TS
6763 
6764    Input Parameter:
6765 .  ts - the TS context
6766 
6767    Output Parameter:
6768 .  names - the names of the components, final string must be NULL
6769 
6770    Level: intermediate
6771 
6772    Notes: If the TS object does not have a TSMonitorLGCtx associated with it then this function is ignored
6773 
6774 .keywords: TS,  vector, monitor, view
6775 
6776 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorLGSetDisplayVariables()
6777 @*/
6778 PetscErrorCode  TSMonitorLGGetVariableNames(TS ts,const char *const **names)
6779 {
6780   PetscInt       i;
6781 
6782   PetscFunctionBegin;
6783   *names = NULL;
6784   for (i=0; i<ts->numbermonitors; i++) {
6785     if (ts->monitor[i] == TSMonitorLGSolution) {
6786       TSMonitorLGCtx  ctx = (TSMonitorLGCtx) ts->monitorcontext[i];
6787       *names = (const char *const *)ctx->names;
6788       break;
6789     }
6790   }
6791   PetscFunctionReturn(0);
6792 }
6793 
6794 #undef __FUNCT__
6795 #define __FUNCT__ "TSMonitorLGCtxSetDisplayVariables"
6796 /*@C
6797    TSMonitorLGCtxSetDisplayVariables - Sets the variables that are to be display in the monitor
6798 
6799    Collective on TS
6800 
6801    Input Parameters:
6802 +  ctx - the TSMonitorLG context
6803 .  displaynames - the names of the components, final string must be NULL
6804 
6805    Level: intermediate
6806 
6807 .keywords: TS,  vector, monitor, view
6808 
6809 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorLGSetVariableNames()
6810 @*/
6811 PetscErrorCode  TSMonitorLGCtxSetDisplayVariables(TSMonitorLGCtx ctx,const char * const *displaynames)
6812 {
6813   PetscInt          j = 0,k;
6814   PetscErrorCode    ierr;
6815 
6816   PetscFunctionBegin;
6817   if (!ctx->names) PetscFunctionReturn(0);
6818   ierr = PetscStrArrayDestroy(&ctx->displaynames);CHKERRQ(ierr);
6819   ierr = PetscStrArrayallocpy(displaynames,&ctx->displaynames);CHKERRQ(ierr);
6820   while (displaynames[j]) j++;
6821   ctx->ndisplayvariables = j;
6822   ierr = PetscMalloc1(ctx->ndisplayvariables,&ctx->displayvariables);CHKERRQ(ierr);
6823   ierr = PetscMalloc1(ctx->ndisplayvariables,&ctx->displayvalues);CHKERRQ(ierr);
6824   j = 0;
6825   while (displaynames[j]) {
6826     k = 0;
6827     while (ctx->names[k]) {
6828       PetscBool flg;
6829       ierr = PetscStrcmp(displaynames[j],ctx->names[k],&flg);CHKERRQ(ierr);
6830       if (flg) {
6831         ctx->displayvariables[j] = k;
6832         break;
6833       }
6834       k++;
6835     }
6836     j++;
6837   }
6838   PetscFunctionReturn(0);
6839 }
6840 
6841 
6842 #undef __FUNCT__
6843 #define __FUNCT__ "TSMonitorLGSetDisplayVariables"
6844 /*@C
6845    TSMonitorLGSetDisplayVariables - Sets the variables that are to be display in the monitor
6846 
6847    Collective on TS
6848 
6849    Input Parameters:
6850 +  ts - the TS context
6851 .  displaynames - the names of the components, final string must be NULL
6852 
6853    Notes: If the TS object does not have a TSMonitorLGCtx associated with it then this function is ignored
6854 
6855    Level: intermediate
6856 
6857 .keywords: TS,  vector, monitor, view
6858 
6859 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorLGSetVariableNames()
6860 @*/
6861 PetscErrorCode  TSMonitorLGSetDisplayVariables(TS ts,const char * const *displaynames)
6862 {
6863   PetscInt          i;
6864   PetscErrorCode    ierr;
6865 
6866   PetscFunctionBegin;
6867   for (i=0; i<ts->numbermonitors; i++) {
6868     if (ts->monitor[i] == TSMonitorLGSolution) {
6869       ierr = TSMonitorLGCtxSetDisplayVariables((TSMonitorLGCtx)ts->monitorcontext[i],displaynames);CHKERRQ(ierr);
6870       break;
6871     }
6872   }
6873   PetscFunctionReturn(0);
6874 }
6875 
6876 #undef __FUNCT__
6877 #define __FUNCT__ "TSMonitorLGSetTransform"
6878 /*@C
6879    TSMonitorLGSetTransform - Solution vector will be transformed by provided function before being displayed
6880 
6881    Collective on TS
6882 
6883    Input Parameters:
6884 +  ts - the TS context
6885 .  transform - the transform function
6886 .  destroy - function to destroy the optional context
6887 -  ctx - optional context used by transform function
6888 
6889    Notes: If the TS object does not have a TSMonitorLGCtx associated with it then this function is ignored
6890 
6891    Level: intermediate
6892 
6893 .keywords: TS,  vector, monitor, view
6894 
6895 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorLGSetVariableNames(), TSMonitorLGCtxSetTransform()
6896 @*/
6897 PetscErrorCode  TSMonitorLGSetTransform(TS ts,PetscErrorCode (*transform)(void*,Vec,Vec*),PetscErrorCode (*destroy)(void*),void *tctx)
6898 {
6899   PetscInt          i;
6900   PetscErrorCode    ierr;
6901 
6902   PetscFunctionBegin;
6903   for (i=0; i<ts->numbermonitors; i++) {
6904     if (ts->monitor[i] == TSMonitorLGSolution) {
6905       ierr = TSMonitorLGCtxSetTransform((TSMonitorLGCtx)ts->monitorcontext[i],transform,destroy,tctx);CHKERRQ(ierr);
6906     }
6907   }
6908   PetscFunctionReturn(0);
6909 }
6910 
6911 #undef __FUNCT__
6912 #define __FUNCT__ "TSMonitorLGCtxSetTransform"
6913 /*@C
6914    TSMonitorLGCtxSetTransform - Solution vector will be transformed by provided function before being displayed
6915 
6916    Collective on TSLGCtx
6917 
6918    Input Parameters:
6919 +  ts - the TS context
6920 .  transform - the transform function
6921 .  destroy - function to destroy the optional context
6922 -  ctx - optional context used by transform function
6923 
6924    Level: intermediate
6925 
6926 .keywords: TS,  vector, monitor, view
6927 
6928 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorLGSetVariableNames(), TSMonitorLGSetTransform()
6929 @*/
6930 PetscErrorCode  TSMonitorLGCtxSetTransform(TSMonitorLGCtx ctx,PetscErrorCode (*transform)(void*,Vec,Vec*),PetscErrorCode (*destroy)(void*),void *tctx)
6931 {
6932   PetscFunctionBegin;
6933   ctx->transform    = transform;
6934   ctx->transformdestroy = destroy;
6935   ctx->transformctx = tctx;
6936   PetscFunctionReturn(0);
6937 }
6938 
6939 #undef __FUNCT__
6940 #define __FUNCT__ "TSMonitorLGError"
6941 /*@C
6942    TSMonitorLGError - Monitors progress of the TS solvers by plotting each component of the solution vector
6943        in a time based line graph
6944 
6945    Collective on TS
6946 
6947    Input Parameters:
6948 +  ts - the TS context
6949 .  step - current time-step
6950 .  ptime - current time
6951 .  u - current solution
6952 -  dctx - TSMonitorLGCtx object created with TSMonitorLGCtxCreate()
6953 
6954    Level: intermediate
6955 
6956    Notes: Each process in a parallel run displays its component errors in a separate window
6957 
6958    The user must provide the solution using TSSetSolutionFunction() to use this monitor.
6959 
6960    Options Database Keys:
6961 .  -ts_monitor_lg_error - create a graphical monitor of error history
6962 
6963 .keywords: TS,  vector, monitor, view
6964 
6965 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSSetSolutionFunction()
6966 @*/
6967 PetscErrorCode  TSMonitorLGError(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dummy)
6968 {
6969   PetscErrorCode    ierr;
6970   TSMonitorLGCtx    ctx = (TSMonitorLGCtx)dummy;
6971   const PetscScalar *yy;
6972   Vec               y;
6973 
6974   PetscFunctionBegin;
6975   if (!step) {
6976     PetscDrawAxis axis;
6977     PetscInt      dim;
6978     ierr = PetscDrawLGGetAxis(ctx->lg,&axis);CHKERRQ(ierr);
6979     ierr = PetscDrawAxisSetLabels(axis,"Error in solution as function of time","Time","Solution");CHKERRQ(ierr);
6980     ierr = VecGetLocalSize(u,&dim);CHKERRQ(ierr);
6981     ierr = PetscDrawLGSetDimension(ctx->lg,dim);CHKERRQ(ierr);
6982     ierr = PetscDrawLGReset(ctx->lg);CHKERRQ(ierr);
6983   }
6984   ierr = VecDuplicate(u,&y);CHKERRQ(ierr);
6985   ierr = TSComputeSolutionFunction(ts,ptime,y);CHKERRQ(ierr);
6986   ierr = VecAXPY(y,-1.0,u);CHKERRQ(ierr);
6987   ierr = VecGetArrayRead(y,&yy);CHKERRQ(ierr);
6988 #if defined(PETSC_USE_COMPLEX)
6989   {
6990     PetscReal *yreal;
6991     PetscInt  i,n;
6992     ierr = VecGetLocalSize(y,&n);CHKERRQ(ierr);
6993     ierr = PetscMalloc1(n,&yreal);CHKERRQ(ierr);
6994     for (i=0; i<n; i++) yreal[i] = PetscRealPart(yy[i]);
6995     ierr = PetscDrawLGAddCommonPoint(ctx->lg,ptime,yreal);CHKERRQ(ierr);
6996     ierr = PetscFree(yreal);CHKERRQ(ierr);
6997   }
6998 #else
6999   ierr = PetscDrawLGAddCommonPoint(ctx->lg,ptime,yy);CHKERRQ(ierr);
7000 #endif
7001   ierr = VecRestoreArrayRead(y,&yy);CHKERRQ(ierr);
7002   ierr = VecDestroy(&y);CHKERRQ(ierr);
7003   if (((ctx->howoften > 0) && (!(step % ctx->howoften))) || ((ctx->howoften == -1) && ts->reason)) {
7004     ierr = PetscDrawLGDraw(ctx->lg);CHKERRQ(ierr);
7005     ierr = PetscDrawLGSave(ctx->lg);CHKERRQ(ierr);
7006   }
7007   PetscFunctionReturn(0);
7008 }
7009 
7010 #undef __FUNCT__
7011 #define __FUNCT__ "TSMonitorLGSNESIterations"
7012 PetscErrorCode TSMonitorLGSNESIterations(TS ts,PetscInt n,PetscReal ptime,Vec v,void *monctx)
7013 {
7014   TSMonitorLGCtx ctx = (TSMonitorLGCtx) monctx;
7015   PetscReal      x   = ptime,y;
7016   PetscErrorCode ierr;
7017   PetscInt       its;
7018 
7019   PetscFunctionBegin;
7020   if (n < 0) PetscFunctionReturn(0); /* -1 indicates interpolated solution */
7021   if (!n) {
7022     PetscDrawAxis axis;
7023     ierr = PetscDrawLGGetAxis(ctx->lg,&axis);CHKERRQ(ierr);
7024     ierr = PetscDrawAxisSetLabels(axis,"Nonlinear iterations as function of time","Time","SNES Iterations");CHKERRQ(ierr);
7025     ierr = PetscDrawLGReset(ctx->lg);CHKERRQ(ierr);
7026     ctx->snes_its = 0;
7027   }
7028   ierr = TSGetSNESIterations(ts,&its);CHKERRQ(ierr);
7029   y    = its - ctx->snes_its;
7030   ierr = PetscDrawLGAddPoint(ctx->lg,&x,&y);CHKERRQ(ierr);
7031   if (((ctx->howoften > 0) && (!(n % ctx->howoften)) && (n > -1)) || ((ctx->howoften == -1) && (n == -1))) {
7032     ierr = PetscDrawLGDraw(ctx->lg);CHKERRQ(ierr);
7033     ierr = PetscDrawLGSave(ctx->lg);CHKERRQ(ierr);
7034   }
7035   ctx->snes_its = its;
7036   PetscFunctionReturn(0);
7037 }
7038 
7039 #undef __FUNCT__
7040 #define __FUNCT__ "TSMonitorLGKSPIterations"
7041 PetscErrorCode TSMonitorLGKSPIterations(TS ts,PetscInt n,PetscReal ptime,Vec v,void *monctx)
7042 {
7043   TSMonitorLGCtx ctx = (TSMonitorLGCtx) monctx;
7044   PetscReal      x   = ptime,y;
7045   PetscErrorCode ierr;
7046   PetscInt       its;
7047 
7048   PetscFunctionBegin;
7049   if (n < 0) PetscFunctionReturn(0); /* -1 indicates interpolated solution */
7050   if (!n) {
7051     PetscDrawAxis axis;
7052     ierr = PetscDrawLGGetAxis(ctx->lg,&axis);CHKERRQ(ierr);
7053     ierr = PetscDrawAxisSetLabels(axis,"Linear iterations as function of time","Time","KSP Iterations");CHKERRQ(ierr);
7054     ierr = PetscDrawLGReset(ctx->lg);CHKERRQ(ierr);
7055     ctx->ksp_its = 0;
7056   }
7057   ierr = TSGetKSPIterations(ts,&its);CHKERRQ(ierr);
7058   y    = its - ctx->ksp_its;
7059   ierr = PetscDrawLGAddPoint(ctx->lg,&x,&y);CHKERRQ(ierr);
7060   if (((ctx->howoften > 0) && (!(n % ctx->howoften)) && (n > -1)) || ((ctx->howoften == -1) && (n == -1))) {
7061     ierr = PetscDrawLGDraw(ctx->lg);CHKERRQ(ierr);
7062     ierr = PetscDrawLGSave(ctx->lg);CHKERRQ(ierr);
7063   }
7064   ctx->ksp_its = its;
7065   PetscFunctionReturn(0);
7066 }
7067 
7068 #undef __FUNCT__
7069 #define __FUNCT__ "TSComputeLinearStability"
7070 /*@
7071    TSComputeLinearStability - computes the linear stability function at a point
7072 
7073    Collective on TS and Vec
7074 
7075    Input Parameters:
7076 +  ts - the TS context
7077 -  xr,xi - real and imaginary part of input arguments
7078 
7079    Output Parameters:
7080 .  yr,yi - real and imaginary part of function value
7081 
7082    Level: developer
7083 
7084 .keywords: TS, compute
7085 
7086 .seealso: TSSetRHSFunction(), TSComputeIFunction()
7087 @*/
7088 PetscErrorCode TSComputeLinearStability(TS ts,PetscReal xr,PetscReal xi,PetscReal *yr,PetscReal *yi)
7089 {
7090   PetscErrorCode ierr;
7091 
7092   PetscFunctionBegin;
7093   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
7094   if (!ts->ops->linearstability) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"Linearized stability function not provided for this method");
7095   ierr = (*ts->ops->linearstability)(ts,xr,xi,yr,yi);CHKERRQ(ierr);
7096   PetscFunctionReturn(0);
7097 }
7098 
7099 /* ------------------------------------------------------------------------*/
7100 #undef __FUNCT__
7101 #define __FUNCT__ "TSMonitorEnvelopeCtxCreate"
7102 /*@C
7103    TSMonitorEnvelopeCtxCreate - Creates a context for use with TSMonitorEnvelope()
7104 
7105    Collective on TS
7106 
7107    Input Parameters:
7108 .  ts  - the ODE solver object
7109 
7110    Output Parameter:
7111 .  ctx - the context
7112 
7113    Level: intermediate
7114 
7115 .keywords: TS, monitor, line graph, residual, seealso
7116 
7117 .seealso: TSMonitorLGTimeStep(), TSMonitorSet(), TSMonitorLGSolution(), TSMonitorLGError()
7118 
7119 @*/
7120 PetscErrorCode  TSMonitorEnvelopeCtxCreate(TS ts,TSMonitorEnvelopeCtx *ctx)
7121 {
7122   PetscErrorCode ierr;
7123 
7124   PetscFunctionBegin;
7125   ierr = PetscNew(ctx);CHKERRQ(ierr);
7126   PetscFunctionReturn(0);
7127 }
7128 
7129 #undef __FUNCT__
7130 #define __FUNCT__ "TSMonitorEnvelope"
7131 /*@C
7132    TSMonitorEnvelope - Monitors the maximum and minimum value of each component of the solution
7133 
7134    Collective on TS
7135 
7136    Input Parameters:
7137 +  ts - the TS context
7138 .  step - current time-step
7139 .  ptime - current time
7140 .  u  - current solution
7141 -  dctx - the envelope context
7142 
7143    Options Database:
7144 .  -ts_monitor_envelope
7145 
7146    Level: intermediate
7147 
7148    Notes: after a solve you can use TSMonitorEnvelopeGetBounds() to access the envelope
7149 
7150 .keywords: TS,  vector, monitor, view
7151 
7152 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorEnvelopeGetBounds(), TSMonitorEnvelopeCtxCreate()
7153 @*/
7154 PetscErrorCode  TSMonitorEnvelope(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dctx)
7155 {
7156   PetscErrorCode       ierr;
7157   TSMonitorEnvelopeCtx ctx = (TSMonitorEnvelopeCtx)dctx;
7158 
7159   PetscFunctionBegin;
7160   if (!ctx->max) {
7161     ierr = VecDuplicate(u,&ctx->max);CHKERRQ(ierr);
7162     ierr = VecDuplicate(u,&ctx->min);CHKERRQ(ierr);
7163     ierr = VecCopy(u,ctx->max);CHKERRQ(ierr);
7164     ierr = VecCopy(u,ctx->min);CHKERRQ(ierr);
7165   } else {
7166     ierr = VecPointwiseMax(ctx->max,u,ctx->max);CHKERRQ(ierr);
7167     ierr = VecPointwiseMin(ctx->min,u,ctx->min);CHKERRQ(ierr);
7168   }
7169   PetscFunctionReturn(0);
7170 }
7171 
7172 
7173 #undef __FUNCT__
7174 #define __FUNCT__ "TSMonitorEnvelopeGetBounds"
7175 /*@C
7176    TSMonitorEnvelopeGetBounds - Gets the bounds for the components of the solution
7177 
7178    Collective on TS
7179 
7180    Input Parameter:
7181 .  ts - the TS context
7182 
7183    Output Parameter:
7184 +  max - the maximum values
7185 -  min - the minimum values
7186 
7187    Notes: If the TS does not have a TSMonitorEnvelopeCtx associated with it then this function is ignored
7188 
7189    Level: intermediate
7190 
7191 .keywords: TS,  vector, monitor, view
7192 
7193 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorLGSetDisplayVariables()
7194 @*/
7195 PetscErrorCode  TSMonitorEnvelopeGetBounds(TS ts,Vec *max,Vec *min)
7196 {
7197   PetscInt i;
7198 
7199   PetscFunctionBegin;
7200   if (max) *max = NULL;
7201   if (min) *min = NULL;
7202   for (i=0; i<ts->numbermonitors; i++) {
7203     if (ts->monitor[i] == TSMonitorEnvelope) {
7204       TSMonitorEnvelopeCtx  ctx = (TSMonitorEnvelopeCtx) ts->monitorcontext[i];
7205       if (max) *max = ctx->max;
7206       if (min) *min = ctx->min;
7207       break;
7208     }
7209   }
7210   PetscFunctionReturn(0);
7211 }
7212 
7213 #undef __FUNCT__
7214 #define __FUNCT__ "TSMonitorEnvelopeCtxDestroy"
7215 /*@C
7216    TSMonitorEnvelopeCtxDestroy - Destroys a context that was created  with TSMonitorEnvelopeCtxCreate().
7217 
7218    Collective on TSMonitorEnvelopeCtx
7219 
7220    Input Parameter:
7221 .  ctx - the monitor context
7222 
7223    Level: intermediate
7224 
7225 .keywords: TS, monitor, line graph, destroy
7226 
7227 .seealso: TSMonitorLGCtxCreate(),  TSMonitorSet(), TSMonitorLGTimeStep()
7228 @*/
7229 PetscErrorCode  TSMonitorEnvelopeCtxDestroy(TSMonitorEnvelopeCtx *ctx)
7230 {
7231   PetscErrorCode ierr;
7232 
7233   PetscFunctionBegin;
7234   ierr = VecDestroy(&(*ctx)->min);CHKERRQ(ierr);
7235   ierr = VecDestroy(&(*ctx)->max);CHKERRQ(ierr);
7236   ierr = PetscFree(*ctx);CHKERRQ(ierr);
7237   PetscFunctionReturn(0);
7238 }
7239 
7240 #undef __FUNCT__
7241 #define __FUNCT__ "TSRollBack"
7242 /*@
7243    TSRollBack - Rolls back one time step
7244 
7245    Collective on TS
7246 
7247    Input Parameter:
7248 .  ts - the TS context obtained from TSCreate()
7249 
7250    Level: advanced
7251 
7252 .keywords: TS, timestep, rollback
7253 
7254 .seealso: TSCreate(), TSSetUp(), TSDestroy(), TSSolve(), TSSetPreStep(), TSSetPreStage(), TSInterpolate()
7255 @*/
7256 PetscErrorCode  TSRollBack(TS ts)
7257 {
7258   PetscErrorCode ierr;
7259 
7260   PetscFunctionBegin;
7261   PetscValidHeaderSpecific(ts, TS_CLASSID,1);
7262   if (ts->steprollback) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_ARG_WRONGSTATE,"TSRollBack already called");
7263   if (!ts->ops->rollback) SETERRQ1(PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"TSRollBack not implemented for type '%s'",((PetscObject)ts)->type_name);
7264   ierr = (*ts->ops->rollback)(ts);CHKERRQ(ierr);
7265   ts->time_step = ts->ptime - ts->ptime_prev;
7266   ts->ptime = ts->ptime_prev;
7267   ts->ptime_prev = ts->ptime_prev_rollback;
7268   ts->steps--; ts->total_steps--;
7269   ts->steprollback = PETSC_TRUE;
7270   PetscFunctionReturn(0);
7271 }
7272 
7273 #undef __FUNCT__
7274 #define __FUNCT__ "TSGetStages"
7275 /*@
7276    TSGetStages - Get the number of stages and stage values
7277 
7278    Input Parameter:
7279 .  ts - the TS context obtained from TSCreate()
7280 
7281    Level: advanced
7282 
7283 .keywords: TS, getstages
7284 
7285 .seealso: TSCreate()
7286 @*/
7287 PetscErrorCode  TSGetStages(TS ts,PetscInt *ns,Vec **Y)
7288 {
7289   PetscErrorCode ierr;
7290 
7291   PetscFunctionBegin;
7292   PetscValidHeaderSpecific(ts, TS_CLASSID,1);
7293   PetscValidPointer(ns,2);
7294 
7295   if (!ts->ops->getstages) *ns=0;
7296   else {
7297     ierr = (*ts->ops->getstages)(ts,ns,Y);CHKERRQ(ierr);
7298   }
7299   PetscFunctionReturn(0);
7300 }
7301 
7302 #undef __FUNCT__
7303 #define __FUNCT__ "TSComputeIJacobianDefaultColor"
7304 /*@C
7305   TSComputeIJacobianDefaultColor - Computes the Jacobian using finite differences and coloring to exploit matrix sparsity.
7306 
7307   Collective on SNES
7308 
7309   Input Parameters:
7310 + ts - the TS context
7311 . t - current timestep
7312 . U - state vector
7313 . Udot - time derivative of state vector
7314 . shift - shift to apply, see note below
7315 - ctx - an optional user context
7316 
7317   Output Parameters:
7318 + J - Jacobian matrix (not altered in this routine)
7319 - B - newly computed Jacobian matrix to use with preconditioner (generally the same as J)
7320 
7321   Level: intermediate
7322 
7323   Notes:
7324   If F(t,U,Udot)=0 is the DAE, the required Jacobian is
7325 
7326   dF/dU + shift*dF/dUdot
7327 
7328   Most users should not need to explicitly call this routine, as it
7329   is used internally within the nonlinear solvers.
7330 
7331   This will first try to get the coloring from the DM.  If the DM type has no coloring
7332   routine, then it will try to get the coloring from the matrix.  This requires that the
7333   matrix have nonzero entries precomputed.
7334 
7335 .keywords: TS, finite differences, Jacobian, coloring, sparse
7336 .seealso: TSSetIJacobian(), MatFDColoringCreate(), MatFDColoringSetFunction()
7337 @*/
7338 PetscErrorCode TSComputeIJacobianDefaultColor(TS ts,PetscReal t,Vec U,Vec Udot,PetscReal shift,Mat J,Mat B,void *ctx)
7339 {
7340   SNES           snes;
7341   MatFDColoring  color;
7342   PetscBool      hascolor, matcolor = PETSC_FALSE;
7343   PetscErrorCode ierr;
7344 
7345   PetscFunctionBegin;
7346   ierr = PetscOptionsGetBool(((PetscObject)ts)->options,((PetscObject) ts)->prefix, "-ts_fd_color_use_mat", &matcolor, NULL);CHKERRQ(ierr);
7347   ierr = PetscObjectQuery((PetscObject) B, "TSMatFDColoring", (PetscObject *) &color);CHKERRQ(ierr);
7348   if (!color) {
7349     DM         dm;
7350     ISColoring iscoloring;
7351 
7352     ierr = TSGetDM(ts, &dm);CHKERRQ(ierr);
7353     ierr = DMHasColoring(dm, &hascolor);CHKERRQ(ierr);
7354     if (hascolor && !matcolor) {
7355       ierr = DMCreateColoring(dm, IS_COLORING_GLOBAL, &iscoloring);CHKERRQ(ierr);
7356       ierr = MatFDColoringCreate(B, iscoloring, &color);CHKERRQ(ierr);
7357       ierr = MatFDColoringSetFunction(color, (PetscErrorCode (*)(void)) SNESTSFormFunction, (void *) ts);CHKERRQ(ierr);
7358       ierr = MatFDColoringSetFromOptions(color);CHKERRQ(ierr);
7359       ierr = MatFDColoringSetUp(B, iscoloring, color);CHKERRQ(ierr);
7360       ierr = ISColoringDestroy(&iscoloring);CHKERRQ(ierr);
7361     } else {
7362       MatColoring mc;
7363 
7364       ierr = MatColoringCreate(B, &mc);CHKERRQ(ierr);
7365       ierr = MatColoringSetDistance(mc, 2);CHKERRQ(ierr);
7366       ierr = MatColoringSetType(mc, MATCOLORINGSL);CHKERRQ(ierr);
7367       ierr = MatColoringSetFromOptions(mc);CHKERRQ(ierr);
7368       ierr = MatColoringApply(mc, &iscoloring);CHKERRQ(ierr);
7369       ierr = MatColoringDestroy(&mc);CHKERRQ(ierr);
7370       ierr = MatFDColoringCreate(B, iscoloring, &color);CHKERRQ(ierr);
7371       ierr = MatFDColoringSetFunction(color, (PetscErrorCode (*)(void)) SNESTSFormFunction, (void *) ts);CHKERRQ(ierr);
7372       ierr = MatFDColoringSetFromOptions(color);CHKERRQ(ierr);
7373       ierr = MatFDColoringSetUp(B, iscoloring, color);CHKERRQ(ierr);
7374       ierr = ISColoringDestroy(&iscoloring);CHKERRQ(ierr);
7375     }
7376     ierr = PetscObjectCompose((PetscObject) B, "TSMatFDColoring", (PetscObject) color);CHKERRQ(ierr);
7377     ierr = PetscObjectDereference((PetscObject) color);CHKERRQ(ierr);
7378   }
7379   ierr = TSGetSNES(ts, &snes);CHKERRQ(ierr);
7380   ierr = MatFDColoringApply(B, color, U, snes);CHKERRQ(ierr);
7381   if (J != B) {
7382     ierr = MatAssemblyBegin(J, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
7383     ierr = MatAssemblyEnd(J, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
7384   }
7385   PetscFunctionReturn(0);
7386 }
7387 
7388 #undef __FUNCT__
7389 #define __FUNCT__ "TSSetFunctionDomainError"
7390 /*@
7391     TSSetFunctionDomainError - Set the function testing if the current state vector is valid
7392 
7393     Input Parameters:
7394     ts - the TS context
7395     func - function called within TSFunctionDomainError
7396 
7397     Level: intermediate
7398 
7399 .keywords: TS, state, domain
7400 .seealso: TSAdaptCheckStage(), TSFunctionDomainError()
7401 @*/
7402 
7403 PetscErrorCode TSSetFunctionDomainError(TS ts, PetscErrorCode (*func)(TS,PetscReal,Vec,PetscBool*))
7404 {
7405   PetscFunctionBegin;
7406   PetscValidHeaderSpecific(ts, TS_CLASSID,1);
7407   ts->functiondomainerror = func;
7408   PetscFunctionReturn(0);
7409 }
7410 
7411 #undef __FUNCT__
7412 #define __FUNCT__ "TSFunctionDomainError"
7413 /*@
7414     TSFunctionDomainError - Check if the current state is valid
7415 
7416     Input Parameters:
7417     ts - the TS context
7418     stagetime - time of the simulation
7419     Y - state vector to check.
7420 
7421     Output Parameter:
7422     accept - Set to PETSC_FALSE if the current state vector is valid.
7423 
7424     Note:
7425     This function should be used to ensure the state is in a valid part of the space.
7426     For example, one can ensure here all values are positive.
7427 
7428     Level: advanced
7429 @*/
7430 PetscErrorCode TSFunctionDomainError(TS ts,PetscReal stagetime,Vec Y,PetscBool* accept)
7431 {
7432   PetscErrorCode ierr;
7433 
7434   PetscFunctionBegin;
7435 
7436   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
7437   *accept = PETSC_TRUE;
7438   if (ts->functiondomainerror) {
7439     PetscStackCallStandard((*ts->functiondomainerror),(ts,stagetime,Y,accept));
7440   }
7441   PetscFunctionReturn(0);
7442 }
7443 
7444 #undef  __FUNCT__
7445 #define __FUNCT__ "TSClone"
7446 /*@C
7447   TSClone - This function clones a time step object.
7448 
7449   Collective on MPI_Comm
7450 
7451   Input Parameter:
7452 . tsin    - The input TS
7453 
7454   Output Parameter:
7455 . tsout   - The output TS (cloned)
7456 
7457   Notes:
7458   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.
7459 
7460   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);
7461 
7462   Level: developer
7463 
7464 .keywords: TS, clone
7465 .seealso: TSCreate(), TSSetType(), TSSetUp(), TSDestroy(), TSSetProblemType()
7466 @*/
7467 PetscErrorCode  TSClone(TS tsin, TS *tsout)
7468 {
7469   TS             t;
7470   PetscErrorCode ierr;
7471   SNES           snes_start;
7472   DM             dm;
7473   TSType         type;
7474 
7475   PetscFunctionBegin;
7476   PetscValidPointer(tsin,1);
7477   *tsout = NULL;
7478 
7479   ierr = PetscHeaderCreate(t, TS_CLASSID, "TS", "Time stepping", "TS", PetscObjectComm((PetscObject)tsin), TSDestroy, TSView);CHKERRQ(ierr);
7480 
7481   /* General TS description */
7482   t->numbermonitors    = 0;
7483   t->setupcalled       = 0;
7484   t->ksp_its           = 0;
7485   t->snes_its          = 0;
7486   t->nwork             = 0;
7487   t->rhsjacobian.time  = -1e20;
7488   t->rhsjacobian.scale = 1.;
7489   t->ijacobian.shift   = 1.;
7490 
7491   ierr = TSGetSNES(tsin,&snes_start);CHKERRQ(ierr);
7492   ierr = TSSetSNES(t,snes_start);CHKERRQ(ierr);
7493 
7494   ierr = TSGetDM(tsin,&dm);CHKERRQ(ierr);
7495   ierr = TSSetDM(t,dm);CHKERRQ(ierr);
7496 
7497   t->adapt = tsin->adapt;
7498   ierr = PetscObjectReference((PetscObject)t->adapt);CHKERRQ(ierr);
7499 
7500   t->problem_type      = tsin->problem_type;
7501   t->ptime             = tsin->ptime;
7502   t->time_step         = tsin->time_step;
7503   t->max_time          = tsin->max_time;
7504   t->steps             = tsin->steps;
7505   t->max_steps         = tsin->max_steps;
7506   t->equation_type     = tsin->equation_type;
7507   t->atol              = tsin->atol;
7508   t->rtol              = tsin->rtol;
7509   t->max_snes_failures = tsin->max_snes_failures;
7510   t->max_reject        = tsin->max_reject;
7511   t->errorifstepfailed = tsin->errorifstepfailed;
7512 
7513   ierr = TSGetType(tsin,&type);CHKERRQ(ierr);
7514   ierr = TSSetType(t,type);CHKERRQ(ierr);
7515 
7516   t->vec_sol           = NULL;
7517 
7518   t->cfltime          = tsin->cfltime;
7519   t->cfltime_local    = tsin->cfltime_local;
7520   t->exact_final_time = tsin->exact_final_time;
7521 
7522   ierr = PetscMemcpy(t->ops,tsin->ops,sizeof(struct _TSOps));CHKERRQ(ierr);
7523 
7524   if (((PetscObject)tsin)->fortran_func_pointers) {
7525     PetscInt i;
7526     ierr = PetscMalloc((10)*sizeof(void(*)(void)),&((PetscObject)t)->fortran_func_pointers);CHKERRQ(ierr);
7527     for (i=0; i<10; i++) {
7528       ((PetscObject)t)->fortran_func_pointers[i] = ((PetscObject)tsin)->fortran_func_pointers[i];
7529     }
7530   }
7531   *tsout = t;
7532   PetscFunctionReturn(0);
7533 }
7534