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