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