xref: /petsc/src/ts/interface/ts.c (revision f32164c8a7f1214ab1224be2134420754e690e9c)
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    TSGetTotalSteps - Deprecated, use TSGetStepNumber().
3072 @*/
3073 PetscErrorCode TSGetTotalSteps(TS ts,PetscInt *steps) { return TSGetStepNumber(ts,steps); }
3074 
3075 /*@
3076    TSSetSolution - Sets the initial solution vector
3077    for use by the TS routines.
3078 
3079    Logically Collective on TS and Vec
3080 
3081    Input Parameters:
3082 +  ts - the TS context obtained from TSCreate()
3083 -  u - the solution vector
3084 
3085    Level: beginner
3086 
3087 .keywords: TS, timestep, set, solution, initial values
3088 @*/
3089 PetscErrorCode  TSSetSolution(TS ts,Vec u)
3090 {
3091   PetscErrorCode ierr;
3092   DM             dm;
3093 
3094   PetscFunctionBegin;
3095   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
3096   PetscValidHeaderSpecific(u,VEC_CLASSID,2);
3097   ierr = PetscObjectReference((PetscObject)u);CHKERRQ(ierr);
3098   ierr = VecDestroy(&ts->vec_sol);CHKERRQ(ierr);
3099   ts->vec_sol = u;
3100 
3101   ierr = TSGetDM(ts,&dm);CHKERRQ(ierr);
3102   ierr = DMShellSetGlobalVector(dm,u);CHKERRQ(ierr);
3103   PetscFunctionReturn(0);
3104 }
3105 
3106 /*@
3107    TSAdjointSetSteps - Sets the number of steps the adjoint solver should take backward in time
3108 
3109    Logically Collective on TS
3110 
3111    Input Parameters:
3112 +  ts - the TS context obtained from TSCreate()
3113 .  steps - number of steps to use
3114 
3115    Level: intermediate
3116 
3117    Notes: Normally one does not call this and TSAdjointSolve() integrates back to the original timestep. One can call this
3118           so as to integrate back to less than the original timestep
3119 
3120 .keywords: TS, timestep, set, maximum, iterations
3121 
3122 .seealso: TSSetExactFinalTime()
3123 @*/
3124 PetscErrorCode  TSAdjointSetSteps(TS ts,PetscInt steps)
3125 {
3126   PetscFunctionBegin;
3127   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
3128   PetscValidLogicalCollectiveInt(ts,steps,2);
3129   if (steps < 0) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_ARG_OUTOFRANGE,"Cannot step back a negative number of steps");
3130   if (steps > ts->steps) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_ARG_OUTOFRANGE,"Cannot step back more than the total number of forward steps");
3131   ts->adjoint_max_steps = steps;
3132   PetscFunctionReturn(0);
3133 }
3134 
3135 /*@
3136    TSSetCostGradients - Sets the initial value of the gradients of the cost function w.r.t. initial values and w.r.t. the problem parameters
3137       for use by the TSAdjoint routines.
3138 
3139    Logically Collective on TS and Vec
3140 
3141    Input Parameters:
3142 +  ts - the TS context obtained from TSCreate()
3143 .  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
3144 -  mu - gradients with respect to the parameters, the number of entries in these vectors is the same as the number of parameters
3145 
3146    Level: beginner
3147 
3148    Notes: the entries in these vectors must be correctly initialized with the values lamda_i = df/dy|finaltime  mu_i = df/dp|finaltime
3149 
3150 .keywords: TS, timestep, set, sensitivity, initial values
3151 @*/
3152 PetscErrorCode  TSSetCostGradients(TS ts,PetscInt numcost,Vec *lambda,Vec *mu)
3153 {
3154   PetscFunctionBegin;
3155   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
3156   PetscValidPointer(lambda,2);
3157   ts->vecs_sensi  = lambda;
3158   ts->vecs_sensip = mu;
3159   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");
3160   ts->numcost  = numcost;
3161   PetscFunctionReturn(0);
3162 }
3163 
3164 /*@C
3165   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.
3166 
3167   Logically Collective on TS
3168 
3169   Input Parameters:
3170 + ts   - The TS context obtained from TSCreate()
3171 - func - The function
3172 
3173   Calling sequence of func:
3174 $ func (TS ts,PetscReal t,Vec y,Mat A,void *ctx);
3175 +   t - current timestep
3176 .   y - input vector (current ODE solution)
3177 .   A - output matrix
3178 -   ctx - [optional] user-defined function context
3179 
3180   Level: intermediate
3181 
3182   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
3183 
3184 .keywords: TS, sensitivity
3185 .seealso:
3186 @*/
3187 PetscErrorCode  TSAdjointSetRHSJacobian(TS ts,Mat Amat,PetscErrorCode (*func)(TS,PetscReal,Vec,Mat,void*),void *ctx)
3188 {
3189   PetscErrorCode ierr;
3190 
3191   PetscFunctionBegin;
3192   PetscValidHeaderSpecific(ts, TS_CLASSID,1);
3193   PetscValidHeaderSpecific(Amat,MAT_CLASSID,2);
3194 
3195   ts->rhsjacobianp    = func;
3196   ts->rhsjacobianpctx = ctx;
3197   if(Amat) {
3198     ierr = PetscObjectReference((PetscObject)Amat);CHKERRQ(ierr);
3199     ierr = MatDestroy(&ts->Jacp);CHKERRQ(ierr);
3200     ts->Jacp = Amat;
3201   }
3202   PetscFunctionReturn(0);
3203 }
3204 
3205 /*@C
3206   TSAdjointComputeRHSJacobian - Runs the user-defined Jacobian function.
3207 
3208   Collective on TS
3209 
3210   Input Parameters:
3211 . ts   - The TS context obtained from TSCreate()
3212 
3213   Level: developer
3214 
3215 .keywords: TS, sensitivity
3216 .seealso: TSAdjointSetRHSJacobian()
3217 @*/
3218 PetscErrorCode  TSAdjointComputeRHSJacobian(TS ts,PetscReal t,Vec X,Mat Amat)
3219 {
3220   PetscErrorCode ierr;
3221 
3222   PetscFunctionBegin;
3223   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
3224   PetscValidHeaderSpecific(X,VEC_CLASSID,3);
3225   PetscValidPointer(Amat,4);
3226 
3227   PetscStackPush("TS user JacobianP function for sensitivity analysis");
3228   ierr = (*ts->rhsjacobianp)(ts,t,X,Amat,ts->rhsjacobianpctx); CHKERRQ(ierr);
3229   PetscStackPop;
3230   PetscFunctionReturn(0);
3231 }
3232 
3233 /*@C
3234     TSSetCostIntegrand - Sets the routine for evaluating the integral term in one or more cost functions
3235 
3236     Logically Collective on TS
3237 
3238     Input Parameters:
3239 +   ts - the TS context obtained from TSCreate()
3240 .   numcost - number of gradients to be computed, this is the number of cost functions
3241 .   costintegral - vector that stores the integral values
3242 .   rf - routine for evaluating the integrand function
3243 .   drdyf - function that computes the gradients of the r's with respect to y,NULL if not a function y
3244 .   drdpf - function that computes the gradients of the r's with respect to p, NULL if not a function of p
3245 .   fwd - flag indicating whether to evaluate cost integral in the forward run or the adjoint run
3246 -   ctx - [optional] user-defined context for private data for the function evaluation routine (may be NULL)
3247 
3248     Calling sequence of rf:
3249 $   PetscErrorCode rf(TS ts,PetscReal t,Vec y,Vec f,void *ctx);
3250 
3251     Calling sequence of drdyf:
3252 $   PetscErroCode drdyf(TS ts,PetscReal t,Vec y,Vec *drdy,void *ctx);
3253 
3254     Calling sequence of drdpf:
3255 $   PetscErroCode drdpf(TS ts,PetscReal t,Vec y,Vec *drdp,void *ctx);
3256 
3257     Level: intermediate
3258 
3259     Notes: For optimization there is usually a single cost function (numcost = 1). For sensitivities there may be multiple cost functions
3260 
3261 .keywords: TS, sensitivity analysis, timestep, set, quadrature, function
3262 
3263 .seealso: TSAdjointSetRHSJacobian(),TSGetCostGradients(), TSSetCostGradients()
3264 @*/
3265 PetscErrorCode  TSSetCostIntegrand(TS ts,PetscInt numcost,Vec costintegral,PetscErrorCode (*rf)(TS,PetscReal,Vec,Vec,void*),
3266                                                           PetscErrorCode (*drdyf)(TS,PetscReal,Vec,Vec*,void*),
3267                                                           PetscErrorCode (*drdpf)(TS,PetscReal,Vec,Vec*,void*),
3268                                                           PetscBool fwd,void *ctx)
3269 {
3270   PetscErrorCode ierr;
3271 
3272   PetscFunctionBegin;
3273   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
3274   if (costintegral) PetscValidHeaderSpecific(costintegral,VEC_CLASSID,3);
3275   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()");
3276   if (!ts->numcost) ts->numcost=numcost;
3277 
3278   if (costintegral) {
3279     ierr = PetscObjectReference((PetscObject)costintegral);CHKERRQ(ierr);
3280     ierr = VecDestroy(&ts->vec_costintegral);CHKERRQ(ierr);
3281     ts->vec_costintegral = costintegral;
3282   } else {
3283     if (!ts->vec_costintegral) { /* Create a seq vec if user does not provide one */
3284       ierr = VecCreateSeq(PETSC_COMM_SELF,numcost,&ts->vec_costintegral);CHKERRQ(ierr);
3285     } else {
3286       ierr = VecSet(ts->vec_costintegral,0.0);CHKERRQ(ierr);
3287     }
3288   }
3289   if (!ts->vec_costintegrand) {
3290     ierr = VecDuplicate(ts->vec_costintegral,&ts->vec_costintegrand);CHKERRQ(ierr);
3291   } else {
3292     ierr = VecSet(ts->vec_costintegrand,0.0);CHKERRQ(ierr);
3293   }
3294   ts->costintegralfwd  = fwd; /* Evaluate the cost integral in forward run if fwd is true */
3295   ts->costintegrand    = rf;
3296   ts->costintegrandctx = ctx;
3297   ts->drdyfunction     = drdyf;
3298   ts->drdpfunction     = drdpf;
3299   PetscFunctionReturn(0);
3300 }
3301 
3302 /*@
3303    TSGetCostIntegral - Returns the values of the integral term in the cost functions.
3304    It is valid to call the routine after a backward run.
3305 
3306    Not Collective
3307 
3308    Input Parameter:
3309 .  ts - the TS context obtained from TSCreate()
3310 
3311    Output Parameter:
3312 .  v - the vector containing the integrals for each cost function
3313 
3314    Level: intermediate
3315 
3316 .seealso: TSSetCostIntegrand()
3317 
3318 .keywords: TS, sensitivity analysis
3319 @*/
3320 PetscErrorCode  TSGetCostIntegral(TS ts,Vec *v)
3321 {
3322   PetscFunctionBegin;
3323   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
3324   PetscValidPointer(v,2);
3325   *v = ts->vec_costintegral;
3326   PetscFunctionReturn(0);
3327 }
3328 
3329 /*@
3330    TSComputeCostIntegrand - Evaluates the integral function in the cost functions.
3331 
3332    Input Parameters:
3333 +  ts - the TS context
3334 .  t - current time
3335 -  y - state vector, i.e. current solution
3336 
3337    Output Parameter:
3338 .  q - vector of size numcost to hold the outputs
3339 
3340    Note:
3341    Most users should not need to explicitly call this routine, as it
3342    is used internally within the sensitivity analysis context.
3343 
3344    Level: developer
3345 
3346 .keywords: TS, compute
3347 
3348 .seealso: TSSetCostIntegrand()
3349 @*/
3350 PetscErrorCode TSComputeCostIntegrand(TS ts,PetscReal t,Vec y,Vec q)
3351 {
3352   PetscErrorCode ierr;
3353 
3354   PetscFunctionBegin;
3355   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
3356   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
3357   PetscValidHeaderSpecific(q,VEC_CLASSID,4);
3358 
3359   ierr = PetscLogEventBegin(TS_FunctionEval,ts,y,q,0);CHKERRQ(ierr);
3360   if (ts->costintegrand) {
3361     PetscStackPush("TS user integrand in the cost function");
3362     ierr = (*ts->costintegrand)(ts,t,y,q,ts->costintegrandctx);CHKERRQ(ierr);
3363     PetscStackPop;
3364   } else {
3365     ierr = VecZeroEntries(q);CHKERRQ(ierr);
3366   }
3367 
3368   ierr = PetscLogEventEnd(TS_FunctionEval,ts,y,q,0);CHKERRQ(ierr);
3369   PetscFunctionReturn(0);
3370 }
3371 
3372 /*@
3373   TSAdjointComputeDRDYFunction - Runs the user-defined DRDY function.
3374 
3375   Collective on TS
3376 
3377   Input Parameters:
3378 . ts   - The TS context obtained from TSCreate()
3379 
3380   Notes:
3381   TSAdjointComputeDRDYFunction() is typically used for sensitivity implementation,
3382   so most users would not generally call this routine themselves.
3383 
3384   Level: developer
3385 
3386 .keywords: TS, sensitivity
3387 .seealso: TSAdjointComputeDRDYFunction()
3388 @*/
3389 PetscErrorCode  TSAdjointComputeDRDYFunction(TS ts,PetscReal t,Vec y,Vec *drdy)
3390 {
3391   PetscErrorCode ierr;
3392 
3393   PetscFunctionBegin;
3394   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
3395   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
3396 
3397   PetscStackPush("TS user DRDY function for sensitivity analysis");
3398   ierr = (*ts->drdyfunction)(ts,t,y,drdy,ts->costintegrandctx); CHKERRQ(ierr);
3399   PetscStackPop;
3400   PetscFunctionReturn(0);
3401 }
3402 
3403 /*@
3404   TSAdjointComputeDRDPFunction - Runs the user-defined DRDP function.
3405 
3406   Collective on TS
3407 
3408   Input Parameters:
3409 . ts   - The TS context obtained from TSCreate()
3410 
3411   Notes:
3412   TSDRDPFunction() is typically used for sensitivity implementation,
3413   so most users would not generally call this routine themselves.
3414 
3415   Level: developer
3416 
3417 .keywords: TS, sensitivity
3418 .seealso: TSAdjointSetDRDPFunction()
3419 @*/
3420 PetscErrorCode  TSAdjointComputeDRDPFunction(TS ts,PetscReal t,Vec y,Vec *drdp)
3421 {
3422   PetscErrorCode ierr;
3423 
3424   PetscFunctionBegin;
3425   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
3426   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
3427 
3428   PetscStackPush("TS user DRDP function for sensitivity analysis");
3429   ierr = (*ts->drdpfunction)(ts,t,y,drdp,ts->costintegrandctx); CHKERRQ(ierr);
3430   PetscStackPop;
3431   PetscFunctionReturn(0);
3432 }
3433 
3434 /*@C
3435   TSSetPreStep - Sets the general-purpose function
3436   called once at the beginning of each time step.
3437 
3438   Logically Collective on TS
3439 
3440   Input Parameters:
3441 + ts   - The TS context obtained from TSCreate()
3442 - func - The function
3443 
3444   Calling sequence of func:
3445 . func (TS ts);
3446 
3447   Level: intermediate
3448 
3449 .keywords: TS, timestep
3450 .seealso: TSSetPreStage(), TSSetPostStage(), TSSetPostStep(), TSStep()
3451 @*/
3452 PetscErrorCode  TSSetPreStep(TS ts, PetscErrorCode (*func)(TS))
3453 {
3454   PetscFunctionBegin;
3455   PetscValidHeaderSpecific(ts, TS_CLASSID,1);
3456   ts->prestep = func;
3457   PetscFunctionReturn(0);
3458 }
3459 
3460 /*@
3461   TSPreStep - Runs the user-defined pre-step function.
3462 
3463   Collective on TS
3464 
3465   Input Parameters:
3466 . ts   - The TS context obtained from TSCreate()
3467 
3468   Notes:
3469   TSPreStep() is typically used within time stepping implementations,
3470   so most users would not generally call this routine themselves.
3471 
3472   Level: developer
3473 
3474 .keywords: TS, timestep
3475 .seealso: TSSetPreStep(), TSPreStage(), TSPostStage(), TSPostStep()
3476 @*/
3477 PetscErrorCode  TSPreStep(TS ts)
3478 {
3479   PetscErrorCode ierr;
3480 
3481   PetscFunctionBegin;
3482   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
3483   if (ts->prestep) {
3484     PetscStackCallStandard((*ts->prestep),(ts));
3485   }
3486   PetscFunctionReturn(0);
3487 }
3488 
3489 /*@C
3490   TSSetPreStage - Sets the general-purpose function
3491   called once at the beginning of each stage.
3492 
3493   Logically Collective on TS
3494 
3495   Input Parameters:
3496 + ts   - The TS context obtained from TSCreate()
3497 - func - The function
3498 
3499   Calling sequence of func:
3500 . PetscErrorCode func(TS ts, PetscReal stagetime);
3501 
3502   Level: intermediate
3503 
3504   Note:
3505   There may be several stages per time step. If the solve for a given stage fails, the step may be rejected and retried.
3506   The time step number being computed can be queried using TSGetStepNumber() and the total size of the step being
3507   attempted can be obtained using TSGetTimeStep(). The time at the start of the step is available via TSGetTime().
3508 
3509 .keywords: TS, timestep
3510 .seealso: TSSetPostStage(), TSSetPreStep(), TSSetPostStep(), TSGetApplicationContext()
3511 @*/
3512 PetscErrorCode  TSSetPreStage(TS ts, PetscErrorCode (*func)(TS,PetscReal))
3513 {
3514   PetscFunctionBegin;
3515   PetscValidHeaderSpecific(ts, TS_CLASSID,1);
3516   ts->prestage = func;
3517   PetscFunctionReturn(0);
3518 }
3519 
3520 /*@C
3521   TSSetPostStage - Sets the general-purpose function
3522   called once at the end of each stage.
3523 
3524   Logically Collective on TS
3525 
3526   Input Parameters:
3527 + ts   - The TS context obtained from TSCreate()
3528 - func - The function
3529 
3530   Calling sequence of func:
3531 . PetscErrorCode func(TS ts, PetscReal stagetime, PetscInt stageindex, Vec* Y);
3532 
3533   Level: intermediate
3534 
3535   Note:
3536   There may be several stages per time step. If the solve for a given stage fails, the step may be rejected and retried.
3537   The time step number being computed can be queried using TSGetStepNumber() and the total size of the step being
3538   attempted can be obtained using TSGetTimeStep(). The time at the start of the step is available via TSGetTime().
3539 
3540 .keywords: TS, timestep
3541 .seealso: TSSetPreStage(), TSSetPreStep(), TSSetPostStep(), TSGetApplicationContext()
3542 @*/
3543 PetscErrorCode  TSSetPostStage(TS ts, PetscErrorCode (*func)(TS,PetscReal,PetscInt,Vec*))
3544 {
3545   PetscFunctionBegin;
3546   PetscValidHeaderSpecific(ts, TS_CLASSID,1);
3547   ts->poststage = func;
3548   PetscFunctionReturn(0);
3549 }
3550 
3551 /*@C
3552   TSSetPostEvaluate - Sets the general-purpose function
3553   called once at the end of each step evaluation.
3554 
3555   Logically Collective on TS
3556 
3557   Input Parameters:
3558 + ts   - The TS context obtained from TSCreate()
3559 - func - The function
3560 
3561   Calling sequence of func:
3562 . PetscErrorCode func(TS ts);
3563 
3564   Level: intermediate
3565 
3566   Note:
3567   Semantically, TSSetPostEvaluate() differs from TSSetPostStep() since the function it sets is called before event-handling
3568   thus guaranteeing the same solution (computed by the time-stepper) will be passed to it. On the other hand, TSPostStep()
3569   may be passed a different solution, possibly changed by the event handler. TSPostEvaluate() is called after the next step
3570   solution is evaluated allowing to modify it, if need be. The solution can be obtained with TSGetSolution(), the time step
3571   with TSGetTimeStep(), and the time at the start of the step is available via TSGetTime()
3572 
3573 .keywords: TS, timestep
3574 .seealso: TSSetPreStage(), TSSetPreStep(), TSSetPostStep(), TSGetApplicationContext()
3575 @*/
3576 PetscErrorCode  TSSetPostEvaluate(TS ts, PetscErrorCode (*func)(TS))
3577 {
3578   PetscFunctionBegin;
3579   PetscValidHeaderSpecific(ts, TS_CLASSID,1);
3580   ts->postevaluate = func;
3581   PetscFunctionReturn(0);
3582 }
3583 
3584 /*@
3585   TSPreStage - Runs the user-defined pre-stage function set using TSSetPreStage()
3586 
3587   Collective on TS
3588 
3589   Input Parameters:
3590 . ts          - The TS context obtained from TSCreate()
3591   stagetime   - The absolute time of the current stage
3592 
3593   Notes:
3594   TSPreStage() is typically used within time stepping implementations,
3595   most users would not generally call this routine themselves.
3596 
3597   Level: developer
3598 
3599 .keywords: TS, timestep
3600 .seealso: TSPostStage(), TSSetPreStep(), TSPreStep(), TSPostStep()
3601 @*/
3602 PetscErrorCode  TSPreStage(TS ts, PetscReal stagetime)
3603 {
3604   PetscErrorCode ierr;
3605 
3606   PetscFunctionBegin;
3607   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
3608   if (ts->prestage) {
3609     PetscStackCallStandard((*ts->prestage),(ts,stagetime));
3610   }
3611   PetscFunctionReturn(0);
3612 }
3613 
3614 /*@
3615   TSPostStage - Runs the user-defined post-stage function set using TSSetPostStage()
3616 
3617   Collective on TS
3618 
3619   Input Parameters:
3620 . ts          - The TS context obtained from TSCreate()
3621   stagetime   - The absolute time of the current stage
3622   stageindex  - Stage number
3623   Y           - Array of vectors (of size = total number
3624                 of stages) with the stage solutions
3625 
3626   Notes:
3627   TSPostStage() is typically used within time stepping implementations,
3628   most users would not generally call this routine themselves.
3629 
3630   Level: developer
3631 
3632 .keywords: TS, timestep
3633 .seealso: TSPreStage(), TSSetPreStep(), TSPreStep(), TSPostStep()
3634 @*/
3635 PetscErrorCode  TSPostStage(TS ts, PetscReal stagetime, PetscInt stageindex, Vec *Y)
3636 {
3637   PetscErrorCode ierr;
3638 
3639   PetscFunctionBegin;
3640   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
3641   if (ts->poststage) {
3642     PetscStackCallStandard((*ts->poststage),(ts,stagetime,stageindex,Y));
3643   }
3644   PetscFunctionReturn(0);
3645 }
3646 
3647 /*@
3648   TSPostEvaluate - Runs the user-defined post-evaluate function set using TSSetPostEvaluate()
3649 
3650   Collective on TS
3651 
3652   Input Parameters:
3653 . ts          - The TS context obtained from TSCreate()
3654 
3655   Notes:
3656   TSPostEvaluate() is typically used within time stepping implementations,
3657   most users would not generally call this routine themselves.
3658 
3659   Level: developer
3660 
3661 .keywords: TS, timestep
3662 .seealso: TSSetPostEvaluate(), TSSetPreStep(), TSPreStep(), TSPostStep()
3663 @*/
3664 PetscErrorCode  TSPostEvaluate(TS ts)
3665 {
3666   PetscErrorCode ierr;
3667 
3668   PetscFunctionBegin;
3669   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
3670   if (ts->postevaluate) {
3671     PetscStackCallStandard((*ts->postevaluate),(ts));
3672   }
3673   PetscFunctionReturn(0);
3674 }
3675 
3676 /*@C
3677   TSSetPostStep - Sets the general-purpose function
3678   called once at the end of each time step.
3679 
3680   Logically Collective on TS
3681 
3682   Input Parameters:
3683 + ts   - The TS context obtained from TSCreate()
3684 - func - The function
3685 
3686   Calling sequence of func:
3687 $ func (TS ts);
3688 
3689   Notes:
3690   The function set by TSSetPostStep() is called after each successful step. The solution vector X
3691   obtained by TSGetSolution() may be different than that computed at the step end if the event handler
3692   locates an event and TSPostEvent() modifies it. Use TSSetPostEvaluate() if an unmodified solution is needed instead.
3693 
3694   Level: intermediate
3695 
3696 .keywords: TS, timestep
3697 .seealso: TSSetPreStep(), TSSetPreStage(), TSSetPostEvaluate(), TSGetTimeStep(), TSGetStepNumber(), TSGetTime()
3698 @*/
3699 PetscErrorCode  TSSetPostStep(TS ts, PetscErrorCode (*func)(TS))
3700 {
3701   PetscFunctionBegin;
3702   PetscValidHeaderSpecific(ts, TS_CLASSID,1);
3703   ts->poststep = func;
3704   PetscFunctionReturn(0);
3705 }
3706 
3707 /*@
3708   TSPostStep - Runs the user-defined post-step function.
3709 
3710   Collective on TS
3711 
3712   Input Parameters:
3713 . ts   - The TS context obtained from TSCreate()
3714 
3715   Notes:
3716   TSPostStep() is typically used within time stepping implementations,
3717   so most users would not generally call this routine themselves.
3718 
3719   Level: developer
3720 
3721 .keywords: TS, timestep
3722 @*/
3723 PetscErrorCode  TSPostStep(TS ts)
3724 {
3725   PetscErrorCode ierr;
3726 
3727   PetscFunctionBegin;
3728   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
3729   if (ts->poststep) {
3730     PetscStackCallStandard((*ts->poststep),(ts));
3731   }
3732   PetscFunctionReturn(0);
3733 }
3734 
3735 /* ------------ Routines to set performance monitoring options ----------- */
3736 
3737 /*@C
3738    TSMonitorSet - Sets an ADDITIONAL function that is to be used at every
3739    timestep to display the iteration's  progress.
3740 
3741    Logically Collective on TS
3742 
3743    Input Parameters:
3744 +  ts - the TS context obtained from TSCreate()
3745 .  monitor - monitoring routine
3746 .  mctx - [optional] user-defined context for private data for the
3747              monitor routine (use NULL if no context is desired)
3748 -  monitordestroy - [optional] routine that frees monitor context
3749           (may be NULL)
3750 
3751    Calling sequence of monitor:
3752 $    int monitor(TS ts,PetscInt steps,PetscReal time,Vec u,void *mctx)
3753 
3754 +    ts - the TS context
3755 .    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)
3756 .    time - current time
3757 .    u - current iterate
3758 -    mctx - [optional] monitoring context
3759 
3760    Notes:
3761    This routine adds an additional monitor to the list of monitors that
3762    already has been loaded.
3763 
3764    Fortran notes: Only a single monitor function can be set for each TS object
3765 
3766    Level: intermediate
3767 
3768 .keywords: TS, timestep, set, monitor
3769 
3770 .seealso: TSMonitorDefault(), TSMonitorCancel()
3771 @*/
3772 PetscErrorCode  TSMonitorSet(TS ts,PetscErrorCode (*monitor)(TS,PetscInt,PetscReal,Vec,void*),void *mctx,PetscErrorCode (*mdestroy)(void**))
3773 {
3774   PetscErrorCode ierr;
3775   PetscInt       i;
3776   PetscBool      identical;
3777 
3778   PetscFunctionBegin;
3779   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
3780   for (i=0; i<ts->numbermonitors;i++) {
3781     ierr = PetscMonitorCompare((PetscErrorCode (*)(void))monitor,mctx,mdestroy,(PetscErrorCode (*)(void))ts->monitor[i],ts->monitorcontext[i],ts->monitordestroy[i],&identical);CHKERRQ(ierr);
3782     if (identical) PetscFunctionReturn(0);
3783   }
3784   if (ts->numbermonitors >= MAXTSMONITORS) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Too many monitors set");
3785   ts->monitor[ts->numbermonitors]          = monitor;
3786   ts->monitordestroy[ts->numbermonitors]   = mdestroy;
3787   ts->monitorcontext[ts->numbermonitors++] = (void*)mctx;
3788   PetscFunctionReturn(0);
3789 }
3790 
3791 /*@C
3792    TSMonitorCancel - Clears all the monitors that have been set on a time-step object.
3793 
3794    Logically Collective on TS
3795 
3796    Input Parameters:
3797 .  ts - the TS context obtained from TSCreate()
3798 
3799    Notes:
3800    There is no way to remove a single, specific monitor.
3801 
3802    Level: intermediate
3803 
3804 .keywords: TS, timestep, set, monitor
3805 
3806 .seealso: TSMonitorDefault(), TSMonitorSet()
3807 @*/
3808 PetscErrorCode  TSMonitorCancel(TS ts)
3809 {
3810   PetscErrorCode ierr;
3811   PetscInt       i;
3812 
3813   PetscFunctionBegin;
3814   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
3815   for (i=0; i<ts->numbermonitors; i++) {
3816     if (ts->monitordestroy[i]) {
3817       ierr = (*ts->monitordestroy[i])(&ts->monitorcontext[i]);CHKERRQ(ierr);
3818     }
3819   }
3820   ts->numbermonitors = 0;
3821   PetscFunctionReturn(0);
3822 }
3823 
3824 /*@C
3825    TSMonitorDefault - The Default monitor, prints the timestep and time for each step
3826 
3827    Level: intermediate
3828 
3829 .keywords: TS, set, monitor
3830 
3831 .seealso:  TSMonitorSet()
3832 @*/
3833 PetscErrorCode TSMonitorDefault(TS ts,PetscInt step,PetscReal ptime,Vec v,PetscViewerAndFormat *vf)
3834 {
3835   PetscErrorCode ierr;
3836   PetscViewer    viewer =  vf->viewer;
3837   PetscBool      iascii,ibinary;
3838 
3839   PetscFunctionBegin;
3840   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,4);
3841   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
3842   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&ibinary);CHKERRQ(ierr);
3843   ierr = PetscViewerPushFormat(viewer,vf->format);CHKERRQ(ierr);
3844   if (iascii) {
3845     ierr = PetscViewerASCIIAddTab(viewer,((PetscObject)ts)->tablevel);CHKERRQ(ierr);
3846     if (step == -1){ /* this indicates it is an interpolated solution */
3847       ierr = PetscViewerASCIIPrintf(viewer,"Interpolated solution at time %g between steps %D and %D\n",(double)ptime,ts->steps-1,ts->steps);CHKERRQ(ierr);
3848     } else {
3849       ierr = PetscViewerASCIIPrintf(viewer,"%D TS dt %g time %g%s",step,(double)ts->time_step,(double)ptime,ts->steprollback ? " (r)\n" : "\n");CHKERRQ(ierr);
3850     }
3851     ierr = PetscViewerASCIISubtractTab(viewer,((PetscObject)ts)->tablevel);CHKERRQ(ierr);
3852   } else if (ibinary) {
3853     PetscMPIInt rank;
3854     ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);CHKERRQ(ierr);
3855     if (!rank) {
3856       PetscBool skipHeader;
3857       PetscInt  classid = REAL_FILE_CLASSID;
3858 
3859       ierr = PetscViewerBinaryGetSkipHeader(viewer,&skipHeader);CHKERRQ(ierr);
3860       if (!skipHeader) {
3861          ierr = PetscViewerBinaryWrite(viewer,&classid,1,PETSC_INT,PETSC_FALSE);CHKERRQ(ierr);
3862        }
3863       ierr = PetscRealView(1,&ptime,viewer);CHKERRQ(ierr);
3864     } else {
3865       ierr = PetscRealView(0,&ptime,viewer);CHKERRQ(ierr);
3866     }
3867   }
3868   ierr = PetscViewerPopFormat(viewer);CHKERRQ(ierr);
3869   PetscFunctionReturn(0);
3870 }
3871 
3872 /*@C
3873    TSAdjointMonitorSet - Sets an ADDITIONAL function that is to be used at every
3874    timestep to display the iteration's  progress.
3875 
3876    Logically Collective on TS
3877 
3878    Input Parameters:
3879 +  ts - the TS context obtained from TSCreate()
3880 .  adjointmonitor - monitoring routine
3881 .  adjointmctx - [optional] user-defined context for private data for the
3882              monitor routine (use NULL if no context is desired)
3883 -  adjointmonitordestroy - [optional] routine that frees monitor context
3884           (may be NULL)
3885 
3886    Calling sequence of monitor:
3887 $    int adjointmonitor(TS ts,PetscInt steps,PetscReal time,Vec u,PetscInt numcost,Vec *lambda, Vec *mu,void *adjointmctx)
3888 
3889 +    ts - the TS context
3890 .    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
3891                                been interpolated to)
3892 .    time - current time
3893 .    u - current iterate
3894 .    numcost - number of cost functionos
3895 .    lambda - sensitivities to initial conditions
3896 .    mu - sensitivities to parameters
3897 -    adjointmctx - [optional] adjoint monitoring context
3898 
3899    Notes:
3900    This routine adds an additional monitor to the list of monitors that
3901    already has been loaded.
3902 
3903    Fortran notes: Only a single monitor function can be set for each TS object
3904 
3905    Level: intermediate
3906 
3907 .keywords: TS, timestep, set, adjoint, monitor
3908 
3909 .seealso: TSAdjointMonitorCancel()
3910 @*/
3911 PetscErrorCode  TSAdjointMonitorSet(TS ts,PetscErrorCode (*adjointmonitor)(TS,PetscInt,PetscReal,Vec,PetscInt,Vec*,Vec*,void*),void *adjointmctx,PetscErrorCode (*adjointmdestroy)(void**))
3912 {
3913   PetscErrorCode ierr;
3914   PetscInt       i;
3915   PetscBool      identical;
3916 
3917   PetscFunctionBegin;
3918   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
3919   for (i=0; i<ts->numbermonitors;i++) {
3920     ierr = PetscMonitorCompare((PetscErrorCode (*)(void))adjointmonitor,adjointmctx,adjointmdestroy,(PetscErrorCode (*)(void))ts->adjointmonitor[i],ts->adjointmonitorcontext[i],ts->adjointmonitordestroy[i],&identical);CHKERRQ(ierr);
3921     if (identical) PetscFunctionReturn(0);
3922   }
3923   if (ts->numberadjointmonitors >= MAXTSMONITORS) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Too many adjoint monitors set");
3924   ts->adjointmonitor[ts->numberadjointmonitors]          = adjointmonitor;
3925   ts->adjointmonitordestroy[ts->numberadjointmonitors]   = adjointmdestroy;
3926   ts->adjointmonitorcontext[ts->numberadjointmonitors++] = (void*)adjointmctx;
3927   PetscFunctionReturn(0);
3928 }
3929 
3930 /*@C
3931    TSAdjointMonitorCancel - Clears all the adjoint monitors that have been set on a time-step object.
3932 
3933    Logically Collective on TS
3934 
3935    Input Parameters:
3936 .  ts - the TS context obtained from TSCreate()
3937 
3938    Notes:
3939    There is no way to remove a single, specific monitor.
3940 
3941    Level: intermediate
3942 
3943 .keywords: TS, timestep, set, adjoint, monitor
3944 
3945 .seealso: TSAdjointMonitorSet()
3946 @*/
3947 PetscErrorCode  TSAdjointMonitorCancel(TS ts)
3948 {
3949   PetscErrorCode ierr;
3950   PetscInt       i;
3951 
3952   PetscFunctionBegin;
3953   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
3954   for (i=0; i<ts->numberadjointmonitors; i++) {
3955     if (ts->adjointmonitordestroy[i]) {
3956       ierr = (*ts->adjointmonitordestroy[i])(&ts->adjointmonitorcontext[i]);CHKERRQ(ierr);
3957     }
3958   }
3959   ts->numberadjointmonitors = 0;
3960   PetscFunctionReturn(0);
3961 }
3962 
3963 /*@C
3964    TSAdjointMonitorDefault - the default monitor of adjoint computations
3965 
3966    Level: intermediate
3967 
3968 .keywords: TS, set, monitor
3969 
3970 .seealso: TSAdjointMonitorSet()
3971 @*/
3972 PetscErrorCode TSAdjointMonitorDefault(TS ts,PetscInt step,PetscReal ptime,Vec v,PetscInt numcost,Vec *lambda,Vec *mu,PetscViewerAndFormat *vf)
3973 {
3974   PetscErrorCode ierr;
3975   PetscViewer    viewer = vf->viewer;
3976 
3977   PetscFunctionBegin;
3978   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,4);
3979   ierr = PetscViewerPushFormat(viewer,vf->format);CHKERRQ(ierr);
3980   ierr = PetscViewerASCIIAddTab(viewer,((PetscObject)ts)->tablevel);CHKERRQ(ierr);
3981   ierr = PetscViewerASCIIPrintf(viewer,"%D TS dt %g time %g%s",step,(double)ts->time_step,(double)ptime,ts->steprollback ? " (r)\n" : "\n");CHKERRQ(ierr);
3982   ierr = PetscViewerASCIISubtractTab(viewer,((PetscObject)ts)->tablevel);CHKERRQ(ierr);
3983   ierr = PetscViewerPopFormat(viewer);CHKERRQ(ierr);
3984   PetscFunctionReturn(0);
3985 }
3986 
3987 /*@
3988    TSInterpolate - Interpolate the solution computed during the previous step to an arbitrary location in the interval
3989 
3990    Collective on TS
3991 
3992    Input Argument:
3993 +  ts - time stepping context
3994 -  t - time to interpolate to
3995 
3996    Output Argument:
3997 .  U - state at given time
3998 
3999    Level: intermediate
4000 
4001    Developer Notes:
4002    TSInterpolate() and the storing of previous steps/stages should be generalized to support delay differential equations and continuous adjoints.
4003 
4004 .keywords: TS, set
4005 
4006 .seealso: TSSetExactFinalTime(), TSSolve()
4007 @*/
4008 PetscErrorCode TSInterpolate(TS ts,PetscReal t,Vec U)
4009 {
4010   PetscErrorCode ierr;
4011 
4012   PetscFunctionBegin;
4013   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
4014   PetscValidHeaderSpecific(U,VEC_CLASSID,3);
4015   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);
4016   if (!ts->ops->interpolate) SETERRQ1(PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"%s does not provide interpolation",((PetscObject)ts)->type_name);
4017   ierr = (*ts->ops->interpolate)(ts,t,U);CHKERRQ(ierr);
4018   PetscFunctionReturn(0);
4019 }
4020 
4021 /*@
4022    TSStep - Steps one time step
4023 
4024    Collective on TS
4025 
4026    Input Parameter:
4027 .  ts - the TS context obtained from TSCreate()
4028 
4029    Level: developer
4030 
4031    Notes:
4032    The public interface for the ODE/DAE solvers is TSSolve(), you should almost for sure be using that routine and not this routine.
4033 
4034    The hook set using TSSetPreStep() is called before each attempt to take the step. In general, the time step size may
4035    be changed due to adaptive error controller or solve failures. Note that steps may contain multiple stages.
4036 
4037    This may over-step the final time provided in TSSetMaxTime() depending on the time-step used. TSSolve() interpolates to exactly the
4038    time provided in TSSetMaxTime(). One can use TSInterpolate() to determine an interpolated solution within the final timestep.
4039 
4040 .keywords: TS, timestep, solve
4041 
4042 .seealso: TSCreate(), TSSetUp(), TSDestroy(), TSSolve(), TSSetPreStep(), TSSetPreStage(), TSSetPostStage(), TSInterpolate()
4043 @*/
4044 PetscErrorCode  TSStep(TS ts)
4045 {
4046   PetscErrorCode   ierr;
4047   static PetscBool cite = PETSC_FALSE;
4048   PetscReal        ptime;
4049 
4050   PetscFunctionBegin;
4051   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
4052   ierr = PetscCitationsRegister("@techreport{tspaper,\n"
4053                                 "  title       = {{PETSc/TS}: A Modern Scalable {DAE/ODE} Solver Library},\n"
4054                                 "  author      = {Shrirang Abhyankar and Jed Brown and Emil Constantinescu and Debojyoti Ghosh and Barry F. Smith},\n"
4055                                 "  type        = {Preprint},\n"
4056                                 "  number      = {ANL/MCS-P5061-0114},\n"
4057                                 "  institution = {Argonne National Laboratory},\n"
4058                                 "  year        = {2014}\n}\n",&cite);CHKERRQ(ierr);
4059 
4060   ierr = TSSetUp(ts);CHKERRQ(ierr);
4061   ierr = TSTrajectorySetUp(ts->trajectory,ts);CHKERRQ(ierr);
4062 
4063   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>");
4064   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()");
4065   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");
4066 
4067   if (!ts->steps) ts->ptime_prev = ts->ptime;
4068   ptime = ts->ptime; ts->ptime_prev_rollback = ts->ptime_prev;
4069   ts->reason = TS_CONVERGED_ITERATING;
4070   if (!ts->ops->step) SETERRQ1(PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"TSStep not implemented for type '%s'",((PetscObject)ts)->type_name);
4071   ierr = PetscLogEventBegin(TS_Step,ts,0,0,0);CHKERRQ(ierr);
4072   ierr = (*ts->ops->step)(ts);CHKERRQ(ierr);
4073   ierr = PetscLogEventEnd(TS_Step,ts,0,0,0);CHKERRQ(ierr);
4074   ts->ptime_prev = ptime;
4075   ts->steps++;
4076   ts->steprollback = PETSC_FALSE;
4077   ts->steprestart  = PETSC_FALSE;
4078 
4079   if (ts->reason < 0) {
4080     if (ts->errorifstepfailed) {
4081       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]);
4082       else SETERRQ1(PetscObjectComm((PetscObject)ts),PETSC_ERR_NOT_CONVERGED,"TSStep has failed due to %s",TSConvergedReasons[ts->reason]);
4083     }
4084   } else if (!ts->reason) {
4085     if (ts->steps >= ts->max_steps) ts->reason = TS_CONVERGED_ITS;
4086     else if (ts->ptime >= ts->max_time) ts->reason = TS_CONVERGED_TIME;
4087   }
4088   PetscFunctionReturn(0);
4089 }
4090 
4091 /*@
4092    TSAdjointStep - Steps one time step backward in the adjoint run
4093 
4094    Collective on TS
4095 
4096    Input Parameter:
4097 .  ts - the TS context obtained from TSCreate()
4098 
4099    Level: intermediate
4100 
4101 .keywords: TS, adjoint, step
4102 
4103 .seealso: TSAdjointSetUp(), TSAdjointSolve()
4104 @*/
4105 PetscErrorCode  TSAdjointStep(TS ts)
4106 {
4107   DM               dm;
4108   PetscErrorCode   ierr;
4109 
4110   PetscFunctionBegin;
4111   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
4112   ierr = TSGetDM(ts,&dm);CHKERRQ(ierr);
4113   ierr = TSAdjointSetUp(ts);CHKERRQ(ierr);
4114 
4115   ierr = VecViewFromOptions(ts->vec_sol,(PetscObject)ts,"-ts_view_solution");CHKERRQ(ierr);
4116 
4117   ts->reason = TS_CONVERGED_ITERATING;
4118   ts->ptime_prev = ts->ptime;
4119   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);
4120   ierr = PetscLogEventBegin(TS_AdjointStep,ts,0,0,0);CHKERRQ(ierr);
4121   ierr = (*ts->ops->adjointstep)(ts);CHKERRQ(ierr);
4122   ierr = PetscLogEventEnd(TS_AdjointStep,ts,0,0,0);CHKERRQ(ierr);
4123   ts->adjoint_steps++; ts->steps--;
4124 
4125   if (ts->reason < 0) {
4126     if (ts->errorifstepfailed) {
4127       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]);
4128       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]);
4129       else SETERRQ1(PetscObjectComm((PetscObject)ts),PETSC_ERR_NOT_CONVERGED,"TSStep has failed due to %s",TSConvergedReasons[ts->reason]);
4130     }
4131   } else if (!ts->reason) {
4132     if (ts->adjoint_steps >= ts->adjoint_max_steps) ts->reason = TS_CONVERGED_ITS;
4133   }
4134   PetscFunctionReturn(0);
4135 }
4136 
4137 /*@
4138    TSEvaluateWLTE - Evaluate the weighted local truncation error norm
4139    at the end of a time step with a given order of accuracy.
4140 
4141    Collective on TS
4142 
4143    Input Arguments:
4144 +  ts - time stepping context
4145 .  wnormtype - norm type, either NORM_2 or NORM_INFINITY
4146 -  order - optional, desired order for the error evaluation or PETSC_DECIDE
4147 
4148    Output Arguments:
4149 +  order - optional, the actual order of the error evaluation
4150 -  wlte - the weighted local truncation error norm
4151 
4152    Level: advanced
4153 
4154    Notes:
4155    If the timestepper cannot evaluate the error in a particular step
4156    (eg. in the first step or restart steps after event handling),
4157    this routine returns wlte=-1.0 .
4158 
4159 .seealso: TSStep(), TSAdapt, TSErrorWeightedNorm()
4160 @*/
4161 PetscErrorCode TSEvaluateWLTE(TS ts,NormType wnormtype,PetscInt *order,PetscReal *wlte)
4162 {
4163   PetscErrorCode ierr;
4164 
4165   PetscFunctionBegin;
4166   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
4167   PetscValidType(ts,1);
4168   PetscValidLogicalCollectiveEnum(ts,wnormtype,4);
4169   if (order) PetscValidIntPointer(order,3);
4170   if (order) PetscValidLogicalCollectiveInt(ts,*order,3);
4171   PetscValidRealPointer(wlte,4);
4172   if (wnormtype != NORM_2 && wnormtype != NORM_INFINITY) SETERRQ1(PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"No support for norm type %s",NormTypes[wnormtype]);
4173   if (!ts->ops->evaluatewlte) SETERRQ1(PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"TSEvaluateWLTE not implemented for type '%s'",((PetscObject)ts)->type_name);
4174   ierr = (*ts->ops->evaluatewlte)(ts,wnormtype,order,wlte);CHKERRQ(ierr);
4175   PetscFunctionReturn(0);
4176 }
4177 
4178 /*@
4179    TSEvaluateStep - Evaluate the solution at the end of a time step with a given order of accuracy.
4180 
4181    Collective on TS
4182 
4183    Input Arguments:
4184 +  ts - time stepping context
4185 .  order - desired order of accuracy
4186 -  done - whether the step was evaluated at this order (pass NULL to generate an error if not available)
4187 
4188    Output Arguments:
4189 .  U - state at the end of the current step
4190 
4191    Level: advanced
4192 
4193    Notes:
4194    This function cannot be called until all stages have been evaluated.
4195    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.
4196 
4197 .seealso: TSStep(), TSAdapt
4198 @*/
4199 PetscErrorCode TSEvaluateStep(TS ts,PetscInt order,Vec U,PetscBool *done)
4200 {
4201   PetscErrorCode ierr;
4202 
4203   PetscFunctionBegin;
4204   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
4205   PetscValidType(ts,1);
4206   PetscValidHeaderSpecific(U,VEC_CLASSID,3);
4207   if (!ts->ops->evaluatestep) SETERRQ1(PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"TSEvaluateStep not implemented for type '%s'",((PetscObject)ts)->type_name);
4208   ierr = (*ts->ops->evaluatestep)(ts,order,U,done);CHKERRQ(ierr);
4209   PetscFunctionReturn(0);
4210 }
4211 
4212 /*@
4213    TSForwardCostIntegral - Evaluate the cost integral in the forward run.
4214 
4215    Collective on TS
4216 
4217    Input Arguments:
4218 .  ts - time stepping context
4219 
4220    Level: advanced
4221 
4222    Notes:
4223    This function cannot be called until TSStep() has been completed.
4224 
4225 .seealso: TSSolve(), TSAdjointCostIntegral()
4226 @*/
4227 PetscErrorCode TSForwardCostIntegral(TS ts)
4228 {
4229   PetscErrorCode ierr;
4230   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
4231   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);
4232   ierr = (*ts->ops->forwardintegral)(ts);CHKERRQ(ierr);
4233   PetscFunctionReturn(0);
4234 }
4235 
4236 /*@
4237    TSSolve - Steps the requested number of timesteps.
4238 
4239    Collective on TS
4240 
4241    Input Parameter:
4242 +  ts - the TS context obtained from TSCreate()
4243 -  u - the solution vector  (can be null if TSSetSolution() was used and TSSetExactFinalTime(ts,TS_EXACTFINALTIME_MATCHSTEP) was not used,
4244                              otherwise must contain the initial conditions and will contain the solution at the final requested time
4245 
4246    Level: beginner
4247 
4248    Notes:
4249    The final time returned by this function may be different from the time of the internally
4250    held state accessible by TSGetSolution() and TSGetTime() because the method may have
4251    stepped over the final time.
4252 
4253 .keywords: TS, timestep, solve
4254 
4255 .seealso: TSCreate(), TSSetSolution(), TSStep(), TSGetTime(), TSGetSolveTime()
4256 @*/
4257 PetscErrorCode TSSolve(TS ts,Vec u)
4258 {
4259   Vec               solution;
4260   PetscErrorCode    ierr;
4261 
4262   PetscFunctionBegin;
4263   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
4264   if (u) PetscValidHeaderSpecific(u,VEC_CLASSID,2);
4265 
4266   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 */
4267     PetscValidHeaderSpecific(u,VEC_CLASSID,2);
4268     if (!ts->vec_sol || u == ts->vec_sol) {
4269       ierr = VecDuplicate(u,&solution);CHKERRQ(ierr);
4270       ierr = TSSetSolution(ts,solution);CHKERRQ(ierr);
4271       ierr = VecDestroy(&solution);CHKERRQ(ierr); /* grant ownership */
4272     }
4273     ierr = VecCopy(u,ts->vec_sol);CHKERRQ(ierr);
4274     if (ts->forward_solve) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"Sensitivity analysis does not support the mode TS_EXACTFINALTIME_INTERPOLATE");
4275   } else if (u) {
4276     ierr = TSSetSolution(ts,u);CHKERRQ(ierr);
4277   }
4278   ierr = TSSetUp(ts);CHKERRQ(ierr);
4279   ierr = TSTrajectorySetUp(ts->trajectory,ts);CHKERRQ(ierr);
4280 
4281   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>");
4282   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()");
4283   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");
4284 
4285   if (ts->forward_solve) {
4286     ierr = TSForwardSetUp(ts);CHKERRQ(ierr);
4287   }
4288 
4289   /* reset number of steps only when the step is not restarted. ARKIMEX
4290      restarts the step after an event. Resetting these counters in such case causes
4291      TSTrajectory to incorrectly save the output files
4292   */
4293   /* reset time step and iteration counters */
4294 
4295   if (!ts->steps) {
4296     ts->ksp_its           = 0;
4297     ts->snes_its          = 0;
4298     ts->num_snes_failures = 0;
4299     ts->reject            = 0;
4300     ts->steprestart       = PETSC_TRUE;
4301     ts->steprollback      = PETSC_FALSE;
4302   }
4303   ts->reason = TS_CONVERGED_ITERATING;
4304 
4305   ierr = TSViewFromOptions(ts,NULL,"-ts_view_pre");CHKERRQ(ierr);
4306 
4307   if (ts->ops->solve) { /* This private interface is transitional and should be removed when all implementations are updated. */
4308     ierr = (*ts->ops->solve)(ts);CHKERRQ(ierr);
4309     if (u) {ierr = VecCopy(ts->vec_sol,u);CHKERRQ(ierr);}
4310     ts->solvetime = ts->ptime;
4311     solution = ts->vec_sol;
4312   } else { /* Step the requested number of timesteps. */
4313     if (ts->steps >= ts->max_steps) ts->reason = TS_CONVERGED_ITS;
4314     else if (ts->ptime >= ts->max_time) ts->reason = TS_CONVERGED_TIME;
4315 
4316     if (!ts->steps) {
4317       ierr = TSTrajectorySet(ts->trajectory,ts,ts->steps,ts->ptime,ts->vec_sol);CHKERRQ(ierr);
4318       ierr = TSEventInitialize(ts->event,ts,ts->ptime,ts->vec_sol);CHKERRQ(ierr);
4319     }
4320 
4321     while (!ts->reason) {
4322       ierr = TSMonitor(ts,ts->steps,ts->ptime,ts->vec_sol);CHKERRQ(ierr);
4323       if (!ts->steprollback) {
4324         ierr = TSPreStep(ts);CHKERRQ(ierr);
4325       }
4326       ierr = TSStep(ts);CHKERRQ(ierr);
4327       if (ts->vec_costintegral && ts->costintegralfwd) { /* Must evaluate the cost integral before event is handled. The cost integral value can also be rolled back. */
4328         ierr = TSForwardCostIntegral(ts);CHKERRQ(ierr);
4329       }
4330       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 */
4331         ierr = TSForwardStep(ts);CHKERRQ(ierr);
4332       }
4333       ierr = TSPostEvaluate(ts);CHKERRQ(ierr);
4334       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. */
4335       if (!ts->steprollback) {
4336         ierr = TSTrajectorySet(ts->trajectory,ts,ts->steps,ts->ptime,ts->vec_sol);CHKERRQ(ierr);
4337         ierr = TSPostStep(ts);CHKERRQ(ierr);
4338       }
4339     }
4340     ierr = TSMonitor(ts,ts->steps,ts->ptime,ts->vec_sol);CHKERRQ(ierr);
4341 
4342     if (ts->exact_final_time == TS_EXACTFINALTIME_INTERPOLATE && ts->ptime > ts->max_time) {
4343       ierr = TSInterpolate(ts,ts->max_time,u);CHKERRQ(ierr);
4344       ts->solvetime = ts->max_time;
4345       solution = u;
4346       ierr = TSMonitor(ts,-1,ts->solvetime,solution);CHKERRQ(ierr);
4347     } else {
4348       if (u) {ierr = VecCopy(ts->vec_sol,u);CHKERRQ(ierr);}
4349       ts->solvetime = ts->ptime;
4350       solution = ts->vec_sol;
4351     }
4352   }
4353 
4354   ierr = TSViewFromOptions(ts,NULL,"-ts_view");CHKERRQ(ierr);
4355   ierr = VecViewFromOptions(solution,NULL,"-ts_view_solution");CHKERRQ(ierr);
4356   ierr = PetscObjectSAWsBlock((PetscObject)ts);CHKERRQ(ierr);
4357   if (ts->adjoint_solve) {
4358     ierr = TSAdjointSolve(ts);CHKERRQ(ierr);
4359   }
4360   PetscFunctionReturn(0);
4361 }
4362 
4363 /*@
4364  TSAdjointCostIntegral - Evaluate the cost integral in the adjoint run.
4365 
4366  Collective on TS
4367 
4368  Input Arguments:
4369  .  ts - time stepping context
4370 
4371  Level: advanced
4372 
4373  Notes:
4374  This function cannot be called until TSAdjointStep() has been completed.
4375 
4376  .seealso: TSAdjointSolve(), TSAdjointStep
4377  @*/
4378 PetscErrorCode TSAdjointCostIntegral(TS ts)
4379 {
4380     PetscErrorCode ierr;
4381     PetscValidHeaderSpecific(ts,TS_CLASSID,1);
4382     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);
4383     ierr = (*ts->ops->adjointintegral)(ts);CHKERRQ(ierr);
4384     PetscFunctionReturn(0);
4385 }
4386 
4387 /*@
4388    TSAdjointSolve - Solves the discrete ajoint problem for an ODE/DAE
4389 
4390    Collective on TS
4391 
4392    Input Parameter:
4393 .  ts - the TS context obtained from TSCreate()
4394 
4395    Options Database:
4396 . -ts_adjoint_view_solution <viewerinfo> - views the first gradient with respect to the initial values
4397 
4398    Level: intermediate
4399 
4400    Notes:
4401    This must be called after a call to TSSolve() that solves the forward problem
4402 
4403    By default this will integrate back to the initial time, one can use TSAdjointSetSteps() to step back to a later time
4404 
4405 .keywords: TS, timestep, solve
4406 
4407 .seealso: TSCreate(), TSSetCostGradients(), TSSetSolution(), TSAdjointStep()
4408 @*/
4409 PetscErrorCode TSAdjointSolve(TS ts)
4410 {
4411   PetscErrorCode    ierr;
4412 
4413   PetscFunctionBegin;
4414   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
4415   ierr = TSAdjointSetUp(ts);CHKERRQ(ierr);
4416 
4417   /* reset time step and iteration counters */
4418   ts->adjoint_steps     = 0;
4419   ts->ksp_its           = 0;
4420   ts->snes_its          = 0;
4421   ts->num_snes_failures = 0;
4422   ts->reject            = 0;
4423   ts->reason            = TS_CONVERGED_ITERATING;
4424 
4425   if (!ts->adjoint_max_steps) ts->adjoint_max_steps = ts->steps;
4426   if (ts->adjoint_steps >= ts->adjoint_max_steps) ts->reason = TS_CONVERGED_ITS;
4427 
4428   while (!ts->reason) {
4429     ierr = TSTrajectoryGet(ts->trajectory,ts,ts->steps,&ts->ptime);CHKERRQ(ierr);
4430     ierr = TSAdjointMonitor(ts,ts->steps,ts->ptime,ts->vec_sol,ts->numcost,ts->vecs_sensi,ts->vecs_sensip);CHKERRQ(ierr);
4431     ierr = TSAdjointEventHandler(ts);CHKERRQ(ierr);
4432     ierr = TSAdjointStep(ts);CHKERRQ(ierr);
4433     if (ts->vec_costintegral && !ts->costintegralfwd) {
4434       ierr = TSAdjointCostIntegral(ts);CHKERRQ(ierr);
4435     }
4436   }
4437   ierr = TSTrajectoryGet(ts->trajectory,ts,ts->steps,&ts->ptime);CHKERRQ(ierr);
4438   ierr = TSAdjointMonitor(ts,ts->steps,ts->ptime,ts->vec_sol,ts->numcost,ts->vecs_sensi,ts->vecs_sensip);CHKERRQ(ierr);
4439   ts->solvetime = ts->ptime;
4440   ierr = TSTrajectoryViewFromOptions(ts->trajectory,NULL,"-ts_trajectory_view");CHKERRQ(ierr);
4441   ierr = VecViewFromOptions(ts->vecs_sensi[0],(PetscObject) ts, "-ts_adjoint_view_solution");CHKERRQ(ierr);
4442   PetscFunctionReturn(0);
4443 }
4444 
4445 /*@C
4446    TSMonitor - Runs all user-provided monitor routines set using TSMonitorSet()
4447 
4448    Collective on TS
4449 
4450    Input Parameters:
4451 +  ts - time stepping context obtained from TSCreate()
4452 .  step - step number that has just completed
4453 .  ptime - model time of the state
4454 -  u - state at the current model time
4455 
4456    Notes:
4457    TSMonitor() is typically used automatically within the time stepping implementations.
4458    Users would almost never call this routine directly.
4459 
4460    A step of -1 indicates that the monitor is being called on a solution obtained by interpolating from computed solutions
4461 
4462    Level: developer
4463 
4464 .keywords: TS, timestep
4465 @*/
4466 PetscErrorCode TSMonitor(TS ts,PetscInt step,PetscReal ptime,Vec u)
4467 {
4468   DM             dm;
4469   PetscInt       i,n = ts->numbermonitors;
4470   PetscErrorCode ierr;
4471 
4472   PetscFunctionBegin;
4473   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
4474   PetscValidHeaderSpecific(u,VEC_CLASSID,4);
4475 
4476   ierr = TSGetDM(ts,&dm);CHKERRQ(ierr);
4477   ierr = DMSetOutputSequenceNumber(dm,step,ptime);CHKERRQ(ierr);
4478 
4479   ierr = VecLockPush(u);CHKERRQ(ierr);
4480   for (i=0; i<n; i++) {
4481     ierr = (*ts->monitor[i])(ts,step,ptime,u,ts->monitorcontext[i]);CHKERRQ(ierr);
4482   }
4483   ierr = VecLockPop(u);CHKERRQ(ierr);
4484   PetscFunctionReturn(0);
4485 }
4486 
4487 /*@C
4488    TSAdjointMonitor - Runs all user-provided adjoint monitor routines set using TSAdjointMonitorSet()
4489 
4490    Collective on TS
4491 
4492    Input Parameters:
4493 +  ts - time stepping context obtained from TSCreate()
4494 .  step - step number that has just completed
4495 .  ptime - model time of the state
4496 .  u - state at the current model time
4497 .  numcost - number of cost functions (dimension of lambda  or mu)
4498 .  lambda - vectors containing the gradients of the cost functions with respect to the ODE/DAE solution variables
4499 -  mu - vectors containing the gradients of the cost functions with respect to the problem parameters
4500 
4501    Notes:
4502    TSAdjointMonitor() is typically used automatically within the time stepping implementations.
4503    Users would almost never call this routine directly.
4504 
4505    Level: developer
4506 
4507 .keywords: TS, timestep
4508 @*/
4509 PetscErrorCode TSAdjointMonitor(TS ts,PetscInt step,PetscReal ptime,Vec u,PetscInt numcost,Vec *lambda, Vec *mu)
4510 {
4511   PetscErrorCode ierr;
4512   PetscInt       i,n = ts->numberadjointmonitors;
4513 
4514   PetscFunctionBegin;
4515   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
4516   PetscValidHeaderSpecific(u,VEC_CLASSID,4);
4517   ierr = VecLockPush(u);CHKERRQ(ierr);
4518   for (i=0; i<n; i++) {
4519     ierr = (*ts->adjointmonitor[i])(ts,step,ptime,u,numcost,lambda,mu,ts->adjointmonitorcontext[i]);CHKERRQ(ierr);
4520   }
4521   ierr = VecLockPop(u);CHKERRQ(ierr);
4522   PetscFunctionReturn(0);
4523 }
4524 
4525 /* ------------------------------------------------------------------------*/
4526 /*@C
4527    TSMonitorLGCtxCreate - Creates a TSMonitorLGCtx context for use with
4528    TS to monitor the solution process graphically in various ways
4529 
4530    Collective on TS
4531 
4532    Input Parameters:
4533 +  host - the X display to open, or null for the local machine
4534 .  label - the title to put in the title bar
4535 .  x, y - the screen coordinates of the upper left coordinate of the window
4536 .  m, n - the screen width and height in pixels
4537 -  howoften - if positive then determines the frequency of the plotting, if -1 then only at the final time
4538 
4539    Output Parameter:
4540 .  ctx - the context
4541 
4542    Options Database Key:
4543 +  -ts_monitor_lg_timestep - automatically sets line graph monitor
4544 .  -ts_monitor_lg_solution - monitor the solution (or certain values of the solution by calling TSMonitorLGSetDisplayVariables() or TSMonitorLGCtxSetDisplayVariables())
4545 .  -ts_monitor_lg_error -  monitor the error
4546 .  -ts_monitor_lg_ksp_iterations - monitor the number of KSP iterations needed for each timestep
4547 .  -ts_monitor_lg_snes_iterations - monitor the number of SNES iterations needed for each timestep
4548 -  -lg_use_markers <true,false> - mark the data points (at each time step) on the plot; default is true
4549 
4550    Notes:
4551    Use TSMonitorLGCtxDestroy() to destroy.
4552 
4553    One can provide a function that transforms the solution before plotting it with TSMonitorLGCtxSetTransform() or TSMonitorLGSetTransform()
4554 
4555    Many of the functions that control the monitoring have two forms: TSMonitorLGSet/GetXXXX() and TSMonitorLGCtxSet/GetXXXX() the first take a TS object as the
4556    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
4557    as the first argument.
4558 
4559    One can control the names displayed for each solution or error variable with TSMonitorLGCtxSetVariableNames() or TSMonitorLGSetVariableNames()
4560 
4561    Level: intermediate
4562 
4563 .keywords: TS, monitor, line graph, residual
4564 
4565 .seealso: TSMonitorLGTimeStep(), TSMonitorSet(), TSMonitorLGSolution(), TSMonitorLGError(), TSMonitorDefault(), VecView(),
4566            TSMonitorLGCtxCreate(), TSMonitorLGCtxSetVariableNames(), TSMonitorLGCtxGetVariableNames(),
4567            TSMonitorLGSetVariableNames(), TSMonitorLGGetVariableNames(), TSMonitorLGSetDisplayVariables(), TSMonitorLGCtxSetDisplayVariables(),
4568            TSMonitorLGCtxSetTransform(), TSMonitorLGSetTransform(), TSMonitorLGError(), TSMonitorLGSNESIterations(), TSMonitorLGKSPIterations(),
4569            TSMonitorEnvelopeCtxCreate(), TSMonitorEnvelopeGetBounds(), TSMonitorEnvelopeCtxDestroy(), TSMonitorEnvelop()
4570 
4571 @*/
4572 PetscErrorCode  TSMonitorLGCtxCreate(MPI_Comm comm,const char host[],const char label[],int x,int y,int m,int n,PetscInt howoften,TSMonitorLGCtx *ctx)
4573 {
4574   PetscDraw      draw;
4575   PetscErrorCode ierr;
4576 
4577   PetscFunctionBegin;
4578   ierr = PetscNew(ctx);CHKERRQ(ierr);
4579   ierr = PetscDrawCreate(comm,host,label,x,y,m,n,&draw);CHKERRQ(ierr);
4580   ierr = PetscDrawSetFromOptions(draw);CHKERRQ(ierr);
4581   ierr = PetscDrawLGCreate(draw,1,&(*ctx)->lg);CHKERRQ(ierr);
4582   ierr = PetscDrawLGSetFromOptions((*ctx)->lg);CHKERRQ(ierr);
4583   ierr = PetscDrawDestroy(&draw);CHKERRQ(ierr);
4584   (*ctx)->howoften = howoften;
4585   PetscFunctionReturn(0);
4586 }
4587 
4588 PetscErrorCode TSMonitorLGTimeStep(TS ts,PetscInt step,PetscReal ptime,Vec v,void *monctx)
4589 {
4590   TSMonitorLGCtx ctx = (TSMonitorLGCtx) monctx;
4591   PetscReal      x   = ptime,y;
4592   PetscErrorCode ierr;
4593 
4594   PetscFunctionBegin;
4595   if (step < 0) PetscFunctionReturn(0); /* -1 indicates an interpolated solution */
4596   if (!step) {
4597     PetscDrawAxis axis;
4598     ierr = PetscDrawLGGetAxis(ctx->lg,&axis);CHKERRQ(ierr);
4599     ierr = PetscDrawAxisSetLabels(axis,"Timestep as function of time","Time","Time Step");CHKERRQ(ierr);
4600     ierr = PetscDrawLGReset(ctx->lg);CHKERRQ(ierr);
4601   }
4602   ierr = TSGetTimeStep(ts,&y);CHKERRQ(ierr);
4603   y =  PetscLog10Real(y);
4604   ierr = PetscDrawLGAddPoint(ctx->lg,&x,&y);CHKERRQ(ierr);
4605   if (((ctx->howoften > 0) && (!(step % ctx->howoften))) || ((ctx->howoften == -1) && ts->reason)) {
4606     ierr = PetscDrawLGDraw(ctx->lg);CHKERRQ(ierr);
4607     ierr = PetscDrawLGSave(ctx->lg);CHKERRQ(ierr);
4608   }
4609   PetscFunctionReturn(0);
4610 }
4611 
4612 /*@C
4613    TSMonitorLGCtxDestroy - Destroys a line graph context that was created
4614    with TSMonitorLGCtxCreate().
4615 
4616    Collective on TSMonitorLGCtx
4617 
4618    Input Parameter:
4619 .  ctx - the monitor context
4620 
4621    Level: intermediate
4622 
4623 .keywords: TS, monitor, line graph, destroy
4624 
4625 .seealso: TSMonitorLGCtxCreate(),  TSMonitorSet(), TSMonitorLGTimeStep();
4626 @*/
4627 PetscErrorCode  TSMonitorLGCtxDestroy(TSMonitorLGCtx *ctx)
4628 {
4629   PetscErrorCode ierr;
4630 
4631   PetscFunctionBegin;
4632   if ((*ctx)->transformdestroy) {
4633     ierr = ((*ctx)->transformdestroy)((*ctx)->transformctx);CHKERRQ(ierr);
4634   }
4635   ierr = PetscDrawLGDestroy(&(*ctx)->lg);CHKERRQ(ierr);
4636   ierr = PetscStrArrayDestroy(&(*ctx)->names);CHKERRQ(ierr);
4637   ierr = PetscStrArrayDestroy(&(*ctx)->displaynames);CHKERRQ(ierr);
4638   ierr = PetscFree((*ctx)->displayvariables);CHKERRQ(ierr);
4639   ierr = PetscFree((*ctx)->displayvalues);CHKERRQ(ierr);
4640   ierr = PetscFree(*ctx);CHKERRQ(ierr);
4641   PetscFunctionReturn(0);
4642 }
4643 
4644 /*@
4645    TSGetTime - Gets the time of the most recently completed step.
4646 
4647    Not Collective
4648 
4649    Input Parameter:
4650 .  ts - the TS context obtained from TSCreate()
4651 
4652    Output Parameter:
4653 .  t  - the current time. This time may not corresponds to the final time set with TSSetMaxTime(), use TSGetSolveTime().
4654 
4655    Level: beginner
4656 
4657    Note:
4658    When called during time step evaluation (e.g. during residual evaluation or via hooks set using TSSetPreStep(),
4659    TSSetPreStage(), TSSetPostStage(), or TSSetPostStep()), the time is the time at the start of the step being evaluated.
4660 
4661 .seealso:  TSGetSolveTime(), TSSetTime(), TSGetTimeStep()
4662 
4663 .keywords: TS, get, time
4664 @*/
4665 PetscErrorCode  TSGetTime(TS ts,PetscReal *t)
4666 {
4667   PetscFunctionBegin;
4668   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
4669   PetscValidRealPointer(t,2);
4670   *t = ts->ptime;
4671   PetscFunctionReturn(0);
4672 }
4673 
4674 /*@
4675    TSGetPrevTime - Gets the starting time of the previously completed step.
4676 
4677    Not Collective
4678 
4679    Input Parameter:
4680 .  ts - the TS context obtained from TSCreate()
4681 
4682    Output Parameter:
4683 .  t  - the previous time
4684 
4685    Level: beginner
4686 
4687 .seealso: TSGetTime(), TSGetSolveTime(), TSGetTimeStep()
4688 
4689 .keywords: TS, get, time
4690 @*/
4691 PetscErrorCode  TSGetPrevTime(TS ts,PetscReal *t)
4692 {
4693   PetscFunctionBegin;
4694   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
4695   PetscValidRealPointer(t,2);
4696   *t = ts->ptime_prev;
4697   PetscFunctionReturn(0);
4698 }
4699 
4700 /*@
4701    TSSetTime - Allows one to reset the time.
4702 
4703    Logically Collective on TS
4704 
4705    Input Parameters:
4706 +  ts - the TS context obtained from TSCreate()
4707 -  time - the time
4708 
4709    Level: intermediate
4710 
4711 .seealso: TSGetTime(), TSSetMaxSteps()
4712 
4713 .keywords: TS, set, time
4714 @*/
4715 PetscErrorCode  TSSetTime(TS ts, PetscReal t)
4716 {
4717   PetscFunctionBegin;
4718   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
4719   PetscValidLogicalCollectiveReal(ts,t,2);
4720   ts->ptime = t;
4721   PetscFunctionReturn(0);
4722 }
4723 
4724 /*@C
4725    TSSetOptionsPrefix - Sets the prefix used for searching for all
4726    TS options in the database.
4727 
4728    Logically Collective on TS
4729 
4730    Input Parameter:
4731 +  ts     - The TS context
4732 -  prefix - The prefix to prepend to all option names
4733 
4734    Notes:
4735    A hyphen (-) must NOT be given at the beginning of the prefix name.
4736    The first character of all runtime options is AUTOMATICALLY the
4737    hyphen.
4738 
4739    Level: advanced
4740 
4741 .keywords: TS, set, options, prefix, database
4742 
4743 .seealso: TSSetFromOptions()
4744 
4745 @*/
4746 PetscErrorCode  TSSetOptionsPrefix(TS ts,const char prefix[])
4747 {
4748   PetscErrorCode ierr;
4749   SNES           snes;
4750 
4751   PetscFunctionBegin;
4752   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
4753   ierr = PetscObjectSetOptionsPrefix((PetscObject)ts,prefix);CHKERRQ(ierr);
4754   ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr);
4755   ierr = SNESSetOptionsPrefix(snes,prefix);CHKERRQ(ierr);
4756   PetscFunctionReturn(0);
4757 }
4758 
4759 /*@C
4760    TSAppendOptionsPrefix - Appends to the prefix used for searching for all
4761    TS options in the database.
4762 
4763    Logically Collective on TS
4764 
4765    Input Parameter:
4766 +  ts     - The TS context
4767 -  prefix - The prefix to prepend to all option names
4768 
4769    Notes:
4770    A hyphen (-) must NOT be given at the beginning of the prefix name.
4771    The first character of all runtime options is AUTOMATICALLY the
4772    hyphen.
4773 
4774    Level: advanced
4775 
4776 .keywords: TS, append, options, prefix, database
4777 
4778 .seealso: TSGetOptionsPrefix()
4779 
4780 @*/
4781 PetscErrorCode  TSAppendOptionsPrefix(TS ts,const char prefix[])
4782 {
4783   PetscErrorCode ierr;
4784   SNES           snes;
4785 
4786   PetscFunctionBegin;
4787   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
4788   ierr = PetscObjectAppendOptionsPrefix((PetscObject)ts,prefix);CHKERRQ(ierr);
4789   ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr);
4790   ierr = SNESAppendOptionsPrefix(snes,prefix);CHKERRQ(ierr);
4791   PetscFunctionReturn(0);
4792 }
4793 
4794 /*@C
4795    TSGetOptionsPrefix - Sets the prefix used for searching for all
4796    TS options in the database.
4797 
4798    Not Collective
4799 
4800    Input Parameter:
4801 .  ts - The TS context
4802 
4803    Output Parameter:
4804 .  prefix - A pointer to the prefix string used
4805 
4806    Notes: On the fortran side, the user should pass in a string 'prifix' of
4807    sufficient length to hold the prefix.
4808 
4809    Level: intermediate
4810 
4811 .keywords: TS, get, options, prefix, database
4812 
4813 .seealso: TSAppendOptionsPrefix()
4814 @*/
4815 PetscErrorCode  TSGetOptionsPrefix(TS ts,const char *prefix[])
4816 {
4817   PetscErrorCode ierr;
4818 
4819   PetscFunctionBegin;
4820   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
4821   PetscValidPointer(prefix,2);
4822   ierr = PetscObjectGetOptionsPrefix((PetscObject)ts,prefix);CHKERRQ(ierr);
4823   PetscFunctionReturn(0);
4824 }
4825 
4826 /*@C
4827    TSGetRHSJacobian - Returns the Jacobian J at the present timestep.
4828 
4829    Not Collective, but parallel objects are returned if TS is parallel
4830 
4831    Input Parameter:
4832 .  ts  - The TS context obtained from TSCreate()
4833 
4834    Output Parameters:
4835 +  Amat - The (approximate) Jacobian J of G, where U_t = G(U,t)  (or NULL)
4836 .  Pmat - The matrix from which the preconditioner is constructed, usually the same as Amat  (or NULL)
4837 .  func - Function to compute the Jacobian of the RHS  (or NULL)
4838 -  ctx - User-defined context for Jacobian evaluation routine  (or NULL)
4839 
4840    Notes: You can pass in NULL for any return argument you do not need.
4841 
4842    Level: intermediate
4843 
4844 .seealso: TSGetTimeStep(), TSGetMatrices(), TSGetTime(), TSGetStepNumber()
4845 
4846 .keywords: TS, timestep, get, matrix, Jacobian
4847 @*/
4848 PetscErrorCode  TSGetRHSJacobian(TS ts,Mat *Amat,Mat *Pmat,TSRHSJacobian *func,void **ctx)
4849 {
4850   PetscErrorCode ierr;
4851   DM             dm;
4852 
4853   PetscFunctionBegin;
4854   if (Amat || Pmat) {
4855     SNES snes;
4856     ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr);
4857     ierr = SNESSetUpMatrices(snes);CHKERRQ(ierr);
4858     ierr = SNESGetJacobian(snes,Amat,Pmat,NULL,NULL);CHKERRQ(ierr);
4859   }
4860   ierr = TSGetDM(ts,&dm);CHKERRQ(ierr);
4861   ierr = DMTSGetRHSJacobian(dm,func,ctx);CHKERRQ(ierr);
4862   PetscFunctionReturn(0);
4863 }
4864 
4865 /*@C
4866    TSGetIJacobian - Returns the implicit Jacobian at the present timestep.
4867 
4868    Not Collective, but parallel objects are returned if TS is parallel
4869 
4870    Input Parameter:
4871 .  ts  - The TS context obtained from TSCreate()
4872 
4873    Output Parameters:
4874 +  Amat  - The (approximate) Jacobian of F(t,U,U_t)
4875 .  Pmat - The matrix from which the preconditioner is constructed, often the same as Amat
4876 .  f   - The function to compute the matrices
4877 - ctx - User-defined context for Jacobian evaluation routine
4878 
4879    Notes: You can pass in NULL for any return argument you do not need.
4880 
4881    Level: advanced
4882 
4883 .seealso: TSGetTimeStep(), TSGetRHSJacobian(), TSGetMatrices(), TSGetTime(), TSGetStepNumber()
4884 
4885 .keywords: TS, timestep, get, matrix, Jacobian
4886 @*/
4887 PetscErrorCode  TSGetIJacobian(TS ts,Mat *Amat,Mat *Pmat,TSIJacobian *f,void **ctx)
4888 {
4889   PetscErrorCode ierr;
4890   DM             dm;
4891 
4892   PetscFunctionBegin;
4893   if (Amat || Pmat) {
4894     SNES snes;
4895     ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr);
4896     ierr = SNESSetUpMatrices(snes);CHKERRQ(ierr);
4897     ierr = SNESGetJacobian(snes,Amat,Pmat,NULL,NULL);CHKERRQ(ierr);
4898   }
4899   ierr = TSGetDM(ts,&dm);CHKERRQ(ierr);
4900   ierr = DMTSGetIJacobian(dm,f,ctx);CHKERRQ(ierr);
4901   PetscFunctionReturn(0);
4902 }
4903 
4904 /*@C
4905    TSMonitorDrawSolution - Monitors progress of the TS solvers by calling
4906    VecView() for the solution at each timestep
4907 
4908    Collective on TS
4909 
4910    Input Parameters:
4911 +  ts - the TS context
4912 .  step - current time-step
4913 .  ptime - current time
4914 -  dummy - either a viewer or NULL
4915 
4916    Options Database:
4917 .   -ts_monitor_draw_solution_initial - show initial solution as well as current solution
4918 
4919    Notes: the initial solution and current solution are not display with a common axis scaling so generally the option -ts_monitor_draw_solution_initial
4920        will look bad
4921 
4922    Level: intermediate
4923 
4924 .keywords: TS,  vector, monitor, view
4925 
4926 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView()
4927 @*/
4928 PetscErrorCode  TSMonitorDrawSolution(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dummy)
4929 {
4930   PetscErrorCode   ierr;
4931   TSMonitorDrawCtx ictx = (TSMonitorDrawCtx)dummy;
4932   PetscDraw        draw;
4933 
4934   PetscFunctionBegin;
4935   if (!step && ictx->showinitial) {
4936     if (!ictx->initialsolution) {
4937       ierr = VecDuplicate(u,&ictx->initialsolution);CHKERRQ(ierr);
4938     }
4939     ierr = VecCopy(u,ictx->initialsolution);CHKERRQ(ierr);
4940   }
4941   if (!(((ictx->howoften > 0) && (!(step % ictx->howoften))) || ((ictx->howoften == -1) && ts->reason))) PetscFunctionReturn(0);
4942 
4943   if (ictx->showinitial) {
4944     PetscReal pause;
4945     ierr = PetscViewerDrawGetPause(ictx->viewer,&pause);CHKERRQ(ierr);
4946     ierr = PetscViewerDrawSetPause(ictx->viewer,0.0);CHKERRQ(ierr);
4947     ierr = VecView(ictx->initialsolution,ictx->viewer);CHKERRQ(ierr);
4948     ierr = PetscViewerDrawSetPause(ictx->viewer,pause);CHKERRQ(ierr);
4949     ierr = PetscViewerDrawSetHold(ictx->viewer,PETSC_TRUE);CHKERRQ(ierr);
4950   }
4951   ierr = VecView(u,ictx->viewer);CHKERRQ(ierr);
4952   if (ictx->showtimestepandtime) {
4953     PetscReal xl,yl,xr,yr,h;
4954     char      time[32];
4955 
4956     ierr = PetscViewerDrawGetDraw(ictx->viewer,0,&draw);CHKERRQ(ierr);
4957     ierr = PetscSNPrintf(time,32,"Timestep %d Time %g",(int)step,(double)ptime);CHKERRQ(ierr);
4958     ierr = PetscDrawGetCoordinates(draw,&xl,&yl,&xr,&yr);CHKERRQ(ierr);
4959     h    = yl + .95*(yr - yl);
4960     ierr = PetscDrawStringCentered(draw,.5*(xl+xr),h,PETSC_DRAW_BLACK,time);CHKERRQ(ierr);
4961     ierr = PetscDrawFlush(draw);CHKERRQ(ierr);
4962   }
4963 
4964   if (ictx->showinitial) {
4965     ierr = PetscViewerDrawSetHold(ictx->viewer,PETSC_FALSE);CHKERRQ(ierr);
4966   }
4967   PetscFunctionReturn(0);
4968 }
4969 
4970 /*@C
4971    TSAdjointMonitorDrawSensi - Monitors progress of the adjoint TS solvers by calling
4972    VecView() for the sensitivities to initial states at each timestep
4973 
4974    Collective on TS
4975 
4976    Input Parameters:
4977 +  ts - the TS context
4978 .  step - current time-step
4979 .  ptime - current time
4980 .  u - current state
4981 .  numcost - number of cost functions
4982 .  lambda - sensitivities to initial conditions
4983 .  mu - sensitivities to parameters
4984 -  dummy - either a viewer or NULL
4985 
4986    Level: intermediate
4987 
4988 .keywords: TS,  vector, adjoint, monitor, view
4989 
4990 .seealso: TSAdjointMonitorSet(), TSAdjointMonitorDefault(), VecView()
4991 @*/
4992 PetscErrorCode  TSAdjointMonitorDrawSensi(TS ts,PetscInt step,PetscReal ptime,Vec u,PetscInt numcost,Vec *lambda,Vec *mu,void *dummy)
4993 {
4994   PetscErrorCode   ierr;
4995   TSMonitorDrawCtx ictx = (TSMonitorDrawCtx)dummy;
4996   PetscDraw        draw;
4997   PetscReal        xl,yl,xr,yr,h;
4998   char             time[32];
4999 
5000   PetscFunctionBegin;
5001   if (!(((ictx->howoften > 0) && (!(step % ictx->howoften))) || ((ictx->howoften == -1) && ts->reason))) PetscFunctionReturn(0);
5002 
5003   ierr = VecView(lambda[0],ictx->viewer);CHKERRQ(ierr);
5004   ierr = PetscViewerDrawGetDraw(ictx->viewer,0,&draw);CHKERRQ(ierr);
5005   ierr = PetscSNPrintf(time,32,"Timestep %d Time %g",(int)step,(double)ptime);CHKERRQ(ierr);
5006   ierr = PetscDrawGetCoordinates(draw,&xl,&yl,&xr,&yr);CHKERRQ(ierr);
5007   h    = yl + .95*(yr - yl);
5008   ierr = PetscDrawStringCentered(draw,.5*(xl+xr),h,PETSC_DRAW_BLACK,time);CHKERRQ(ierr);
5009   ierr = PetscDrawFlush(draw);CHKERRQ(ierr);
5010   PetscFunctionReturn(0);
5011 }
5012 
5013 /*@C
5014    TSMonitorDrawSolutionPhase - Monitors progress of the TS solvers by plotting the solution as a phase diagram
5015 
5016    Collective on TS
5017 
5018    Input Parameters:
5019 +  ts - the TS context
5020 .  step - current time-step
5021 .  ptime - current time
5022 -  dummy - either a viewer or NULL
5023 
5024    Level: intermediate
5025 
5026 .keywords: TS,  vector, monitor, view
5027 
5028 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView()
5029 @*/
5030 PetscErrorCode  TSMonitorDrawSolutionPhase(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dummy)
5031 {
5032   PetscErrorCode    ierr;
5033   TSMonitorDrawCtx  ictx = (TSMonitorDrawCtx)dummy;
5034   PetscDraw         draw;
5035   PetscDrawAxis     axis;
5036   PetscInt          n;
5037   PetscMPIInt       size;
5038   PetscReal         U0,U1,xl,yl,xr,yr,h;
5039   char              time[32];
5040   const PetscScalar *U;
5041 
5042   PetscFunctionBegin;
5043   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)ts),&size);CHKERRQ(ierr);
5044   if (size != 1) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"Only allowed for sequential runs");
5045   ierr = VecGetSize(u,&n);CHKERRQ(ierr);
5046   if (n != 2) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"Only for ODEs with two unknowns");
5047 
5048   ierr = PetscViewerDrawGetDraw(ictx->viewer,0,&draw);CHKERRQ(ierr);
5049   ierr = PetscViewerDrawGetDrawAxis(ictx->viewer,0,&axis);CHKERRQ(ierr);
5050   ierr = PetscDrawAxisGetLimits(axis,&xl,&xr,&yl,&yr);CHKERRQ(ierr);
5051   if (!step) {
5052     ierr = PetscDrawClear(draw);CHKERRQ(ierr);
5053     ierr = PetscDrawAxisDraw(axis);CHKERRQ(ierr);
5054   }
5055 
5056   ierr = VecGetArrayRead(u,&U);CHKERRQ(ierr);
5057   U0 = PetscRealPart(U[0]);
5058   U1 = PetscRealPart(U[1]);
5059   ierr = VecRestoreArrayRead(u,&U);CHKERRQ(ierr);
5060   if ((U0 < xl) || (U1 < yl) || (U0 > xr) || (U1 > yr)) PetscFunctionReturn(0);
5061 
5062   ierr = PetscDrawCollectiveBegin(draw);CHKERRQ(ierr);
5063   ierr = PetscDrawPoint(draw,U0,U1,PETSC_DRAW_BLACK);CHKERRQ(ierr);
5064   if (ictx->showtimestepandtime) {
5065     ierr = PetscDrawGetCoordinates(draw,&xl,&yl,&xr,&yr);CHKERRQ(ierr);
5066     ierr = PetscSNPrintf(time,32,"Timestep %d Time %g",(int)step,(double)ptime);CHKERRQ(ierr);
5067     h    = yl + .95*(yr - yl);
5068     ierr = PetscDrawStringCentered(draw,.5*(xl+xr),h,PETSC_DRAW_BLACK,time);CHKERRQ(ierr);
5069   }
5070   ierr = PetscDrawCollectiveEnd(draw);CHKERRQ(ierr);
5071   ierr = PetscDrawFlush(draw);CHKERRQ(ierr);
5072   ierr = PetscDrawPause(draw);CHKERRQ(ierr);
5073   ierr = PetscDrawSave(draw);CHKERRQ(ierr);
5074   PetscFunctionReturn(0);
5075 }
5076 
5077 /*@C
5078    TSMonitorDrawCtxDestroy - Destroys the monitor context for TSMonitorDrawSolution()
5079 
5080    Collective on TS
5081 
5082    Input Parameters:
5083 .    ctx - the monitor context
5084 
5085    Level: intermediate
5086 
5087 .keywords: TS,  vector, monitor, view
5088 
5089 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorDrawSolution(), TSMonitorDrawError()
5090 @*/
5091 PetscErrorCode  TSMonitorDrawCtxDestroy(TSMonitorDrawCtx *ictx)
5092 {
5093   PetscErrorCode ierr;
5094 
5095   PetscFunctionBegin;
5096   ierr = PetscViewerDestroy(&(*ictx)->viewer);CHKERRQ(ierr);
5097   ierr = VecDestroy(&(*ictx)->initialsolution);CHKERRQ(ierr);
5098   ierr = PetscFree(*ictx);CHKERRQ(ierr);
5099   PetscFunctionReturn(0);
5100 }
5101 
5102 /*@C
5103    TSMonitorDrawCtxCreate - Creates the monitor context for TSMonitorDrawCtx
5104 
5105    Collective on TS
5106 
5107    Input Parameter:
5108 .    ts - time-step context
5109 
5110    Output Patameter:
5111 .    ctx - the monitor context
5112 
5113    Options Database:
5114 .   -ts_monitor_draw_solution_initial - show initial solution as well as current solution
5115 
5116    Level: intermediate
5117 
5118 .keywords: TS,  vector, monitor, view
5119 
5120 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorDrawCtx()
5121 @*/
5122 PetscErrorCode  TSMonitorDrawCtxCreate(MPI_Comm comm,const char host[],const char label[],int x,int y,int m,int n,PetscInt howoften,TSMonitorDrawCtx *ctx)
5123 {
5124   PetscErrorCode   ierr;
5125 
5126   PetscFunctionBegin;
5127   ierr = PetscNew(ctx);CHKERRQ(ierr);
5128   ierr = PetscViewerDrawOpen(comm,host,label,x,y,m,n,&(*ctx)->viewer);CHKERRQ(ierr);
5129   ierr = PetscViewerSetFromOptions((*ctx)->viewer);CHKERRQ(ierr);
5130 
5131   (*ctx)->howoften    = howoften;
5132   (*ctx)->showinitial = PETSC_FALSE;
5133   ierr = PetscOptionsGetBool(NULL,NULL,"-ts_monitor_draw_solution_initial",&(*ctx)->showinitial,NULL);CHKERRQ(ierr);
5134 
5135   (*ctx)->showtimestepandtime = PETSC_FALSE;
5136   ierr = PetscOptionsGetBool(NULL,NULL,"-ts_monitor_draw_solution_show_time",&(*ctx)->showtimestepandtime,NULL);CHKERRQ(ierr);
5137   PetscFunctionReturn(0);
5138 }
5139 
5140 /*@C
5141    TSMonitorDrawError - Monitors progress of the TS solvers by calling
5142    VecView() for the error at each timestep
5143 
5144    Collective on TS
5145 
5146    Input Parameters:
5147 +  ts - the TS context
5148 .  step - current time-step
5149 .  ptime - current time
5150 -  dummy - either a viewer or NULL
5151 
5152    Level: intermediate
5153 
5154 .keywords: TS,  vector, monitor, view
5155 
5156 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView()
5157 @*/
5158 PetscErrorCode  TSMonitorDrawError(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dummy)
5159 {
5160   PetscErrorCode   ierr;
5161   TSMonitorDrawCtx ctx    = (TSMonitorDrawCtx)dummy;
5162   PetscViewer      viewer = ctx->viewer;
5163   Vec              work;
5164 
5165   PetscFunctionBegin;
5166   if (!(((ctx->howoften > 0) && (!(step % ctx->howoften))) || ((ctx->howoften == -1) && ts->reason))) PetscFunctionReturn(0);
5167   ierr = VecDuplicate(u,&work);CHKERRQ(ierr);
5168   ierr = TSComputeSolutionFunction(ts,ptime,work);CHKERRQ(ierr);
5169   ierr = VecAXPY(work,-1.0,u);CHKERRQ(ierr);
5170   ierr = VecView(work,viewer);CHKERRQ(ierr);
5171   ierr = VecDestroy(&work);CHKERRQ(ierr);
5172   PetscFunctionReturn(0);
5173 }
5174 
5175 #include <petsc/private/dmimpl.h>
5176 /*@
5177    TSSetDM - Sets the DM that may be used by some nonlinear solvers or preconditioners under the TS
5178 
5179    Logically Collective on TS and DM
5180 
5181    Input Parameters:
5182 +  ts - the ODE integrator object
5183 -  dm - the dm, cannot be NULL
5184 
5185    Level: intermediate
5186 
5187 .seealso: TSGetDM(), SNESSetDM(), SNESGetDM()
5188 @*/
5189 PetscErrorCode  TSSetDM(TS ts,DM dm)
5190 {
5191   PetscErrorCode ierr;
5192   SNES           snes;
5193   DMTS           tsdm;
5194 
5195   PetscFunctionBegin;
5196   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
5197   PetscValidHeaderSpecific(dm,DM_CLASSID,2);
5198   ierr = PetscObjectReference((PetscObject)dm);CHKERRQ(ierr);
5199   if (ts->dm) {               /* Move the DMTS context over to the new DM unless the new DM already has one */
5200     if (ts->dm->dmts && !dm->dmts) {
5201       ierr = DMCopyDMTS(ts->dm,dm);CHKERRQ(ierr);
5202       ierr = DMGetDMTS(ts->dm,&tsdm);CHKERRQ(ierr);
5203       if (tsdm->originaldm == ts->dm) { /* Grant write privileges to the replacement DM */
5204         tsdm->originaldm = dm;
5205       }
5206     }
5207     ierr = DMDestroy(&ts->dm);CHKERRQ(ierr);
5208   }
5209   ts->dm = dm;
5210 
5211   ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr);
5212   ierr = SNESSetDM(snes,dm);CHKERRQ(ierr);
5213   PetscFunctionReturn(0);
5214 }
5215 
5216 /*@
5217    TSGetDM - Gets the DM that may be used by some preconditioners
5218 
5219    Not Collective
5220 
5221    Input Parameter:
5222 . ts - the preconditioner context
5223 
5224    Output Parameter:
5225 .  dm - the dm
5226 
5227    Level: intermediate
5228 
5229 .seealso: TSSetDM(), SNESSetDM(), SNESGetDM()
5230 @*/
5231 PetscErrorCode  TSGetDM(TS ts,DM *dm)
5232 {
5233   PetscErrorCode ierr;
5234 
5235   PetscFunctionBegin;
5236   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
5237   if (!ts->dm) {
5238     ierr = DMShellCreate(PetscObjectComm((PetscObject)ts),&ts->dm);CHKERRQ(ierr);
5239     if (ts->snes) {ierr = SNESSetDM(ts->snes,ts->dm);CHKERRQ(ierr);}
5240   }
5241   *dm = ts->dm;
5242   PetscFunctionReturn(0);
5243 }
5244 
5245 /*@
5246    SNESTSFormFunction - Function to evaluate nonlinear residual
5247 
5248    Logically Collective on SNES
5249 
5250    Input Parameter:
5251 + snes - nonlinear solver
5252 . U - the current state at which to evaluate the residual
5253 - ctx - user context, must be a TS
5254 
5255    Output Parameter:
5256 . F - the nonlinear residual
5257 
5258    Notes:
5259    This function is not normally called by users and is automatically registered with the SNES used by TS.
5260    It is most frequently passed to MatFDColoringSetFunction().
5261 
5262    Level: advanced
5263 
5264 .seealso: SNESSetFunction(), MatFDColoringSetFunction()
5265 @*/
5266 PetscErrorCode  SNESTSFormFunction(SNES snes,Vec U,Vec F,void *ctx)
5267 {
5268   TS             ts = (TS)ctx;
5269   PetscErrorCode ierr;
5270 
5271   PetscFunctionBegin;
5272   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
5273   PetscValidHeaderSpecific(U,VEC_CLASSID,2);
5274   PetscValidHeaderSpecific(F,VEC_CLASSID,3);
5275   PetscValidHeaderSpecific(ts,TS_CLASSID,4);
5276   ierr = (ts->ops->snesfunction)(snes,U,F,ts);CHKERRQ(ierr);
5277   PetscFunctionReturn(0);
5278 }
5279 
5280 /*@
5281    SNESTSFormJacobian - Function to evaluate the Jacobian
5282 
5283    Collective on SNES
5284 
5285    Input Parameter:
5286 + snes - nonlinear solver
5287 . U - the current state at which to evaluate the residual
5288 - ctx - user context, must be a TS
5289 
5290    Output Parameter:
5291 + A - the Jacobian
5292 . B - the preconditioning matrix (may be the same as A)
5293 - flag - indicates any structure change in the matrix
5294 
5295    Notes:
5296    This function is not normally called by users and is automatically registered with the SNES used by TS.
5297 
5298    Level: developer
5299 
5300 .seealso: SNESSetJacobian()
5301 @*/
5302 PetscErrorCode  SNESTSFormJacobian(SNES snes,Vec U,Mat A,Mat B,void *ctx)
5303 {
5304   TS             ts = (TS)ctx;
5305   PetscErrorCode ierr;
5306 
5307   PetscFunctionBegin;
5308   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
5309   PetscValidHeaderSpecific(U,VEC_CLASSID,2);
5310   PetscValidPointer(A,3);
5311   PetscValidHeaderSpecific(A,MAT_CLASSID,3);
5312   PetscValidPointer(B,4);
5313   PetscValidHeaderSpecific(B,MAT_CLASSID,4);
5314   PetscValidHeaderSpecific(ts,TS_CLASSID,6);
5315   ierr = (ts->ops->snesjacobian)(snes,U,A,B,ts);CHKERRQ(ierr);
5316   PetscFunctionReturn(0);
5317 }
5318 
5319 /*@C
5320    TSComputeRHSFunctionLinear - Evaluate the right hand side via the user-provided Jacobian, for linear problems Udot = A U only
5321 
5322    Collective on TS
5323 
5324    Input Arguments:
5325 +  ts - time stepping context
5326 .  t - time at which to evaluate
5327 .  U - state at which to evaluate
5328 -  ctx - context
5329 
5330    Output Arguments:
5331 .  F - right hand side
5332 
5333    Level: intermediate
5334 
5335    Notes:
5336    This function is intended to be passed to TSSetRHSFunction() to evaluate the right hand side for linear problems.
5337    The matrix (and optionally the evaluation context) should be passed to TSSetRHSJacobian().
5338 
5339 .seealso: TSSetRHSFunction(), TSSetRHSJacobian(), TSComputeRHSJacobianConstant()
5340 @*/
5341 PetscErrorCode TSComputeRHSFunctionLinear(TS ts,PetscReal t,Vec U,Vec F,void *ctx)
5342 {
5343   PetscErrorCode ierr;
5344   Mat            Arhs,Brhs;
5345 
5346   PetscFunctionBegin;
5347   ierr = TSGetRHSMats_Private(ts,&Arhs,&Brhs);CHKERRQ(ierr);
5348   ierr = TSComputeRHSJacobian(ts,t,U,Arhs,Brhs);CHKERRQ(ierr);
5349   ierr = MatMult(Arhs,U,F);CHKERRQ(ierr);
5350   PetscFunctionReturn(0);
5351 }
5352 
5353 /*@C
5354    TSComputeRHSJacobianConstant - Reuses a Jacobian that is time-independent.
5355 
5356    Collective on TS
5357 
5358    Input Arguments:
5359 +  ts - time stepping context
5360 .  t - time at which to evaluate
5361 .  U - state at which to evaluate
5362 -  ctx - context
5363 
5364    Output Arguments:
5365 +  A - pointer to operator
5366 .  B - pointer to preconditioning matrix
5367 -  flg - matrix structure flag
5368 
5369    Level: intermediate
5370 
5371    Notes:
5372    This function is intended to be passed to TSSetRHSJacobian() to evaluate the Jacobian for linear time-independent problems.
5373 
5374 .seealso: TSSetRHSFunction(), TSSetRHSJacobian(), TSComputeRHSFunctionLinear()
5375 @*/
5376 PetscErrorCode TSComputeRHSJacobianConstant(TS ts,PetscReal t,Vec U,Mat A,Mat B,void *ctx)
5377 {
5378   PetscFunctionBegin;
5379   PetscFunctionReturn(0);
5380 }
5381 
5382 /*@C
5383    TSComputeIFunctionLinear - Evaluate the left hand side via the user-provided Jacobian, for linear problems only
5384 
5385    Collective on TS
5386 
5387    Input Arguments:
5388 +  ts - time stepping context
5389 .  t - time at which to evaluate
5390 .  U - state at which to evaluate
5391 .  Udot - time derivative of state vector
5392 -  ctx - context
5393 
5394    Output Arguments:
5395 .  F - left hand side
5396 
5397    Level: intermediate
5398 
5399    Notes:
5400    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
5401    user is required to write their own TSComputeIFunction.
5402    This function is intended to be passed to TSSetIFunction() to evaluate the left hand side for linear problems.
5403    The matrix (and optionally the evaluation context) should be passed to TSSetIJacobian().
5404 
5405    Note that using this function is NOT equivalent to using TSComputeRHSFunctionLinear() since that solves Udot = A U
5406 
5407 .seealso: TSSetIFunction(), TSSetIJacobian(), TSComputeIJacobianConstant(), TSComputeRHSFunctionLinear()
5408 @*/
5409 PetscErrorCode TSComputeIFunctionLinear(TS ts,PetscReal t,Vec U,Vec Udot,Vec F,void *ctx)
5410 {
5411   PetscErrorCode ierr;
5412   Mat            A,B;
5413 
5414   PetscFunctionBegin;
5415   ierr = TSGetIJacobian(ts,&A,&B,NULL,NULL);CHKERRQ(ierr);
5416   ierr = TSComputeIJacobian(ts,t,U,Udot,1.0,A,B,PETSC_TRUE);CHKERRQ(ierr);
5417   ierr = MatMult(A,Udot,F);CHKERRQ(ierr);
5418   PetscFunctionReturn(0);
5419 }
5420 
5421 /*@C
5422    TSComputeIJacobianConstant - Reuses a time-independent for a semi-implicit DAE or ODE
5423 
5424    Collective on TS
5425 
5426    Input Arguments:
5427 +  ts - time stepping context
5428 .  t - time at which to evaluate
5429 .  U - state at which to evaluate
5430 .  Udot - time derivative of state vector
5431 .  shift - shift to apply
5432 -  ctx - context
5433 
5434    Output Arguments:
5435 +  A - pointer to operator
5436 .  B - pointer to preconditioning matrix
5437 -  flg - matrix structure flag
5438 
5439    Level: advanced
5440 
5441    Notes:
5442    This function is intended to be passed to TSSetIJacobian() to evaluate the Jacobian for linear time-independent problems.
5443 
5444    It is only appropriate for problems of the form
5445 
5446 $     M Udot = F(U,t)
5447 
5448   where M is constant and F is non-stiff.  The user must pass M to TSSetIJacobian().  The current implementation only
5449   works with IMEX time integration methods such as TSROSW and TSARKIMEX, since there is no support for de-constructing
5450   an implicit operator of the form
5451 
5452 $    shift*M + J
5453 
5454   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
5455   a copy of M or reassemble it when requested.
5456 
5457 .seealso: TSSetIFunction(), TSSetIJacobian(), TSComputeIFunctionLinear()
5458 @*/
5459 PetscErrorCode TSComputeIJacobianConstant(TS ts,PetscReal t,Vec U,Vec Udot,PetscReal shift,Mat A,Mat B,void *ctx)
5460 {
5461   PetscErrorCode ierr;
5462 
5463   PetscFunctionBegin;
5464   ierr = MatScale(A, shift / ts->ijacobian.shift);CHKERRQ(ierr);
5465   ts->ijacobian.shift = shift;
5466   PetscFunctionReturn(0);
5467 }
5468 
5469 /*@
5470    TSGetEquationType - Gets the type of the equation that TS is solving.
5471 
5472    Not Collective
5473 
5474    Input Parameter:
5475 .  ts - the TS context
5476 
5477    Output Parameter:
5478 .  equation_type - see TSEquationType
5479 
5480    Level: beginner
5481 
5482 .keywords: TS, equation type
5483 
5484 .seealso: TSSetEquationType(), TSEquationType
5485 @*/
5486 PetscErrorCode  TSGetEquationType(TS ts,TSEquationType *equation_type)
5487 {
5488   PetscFunctionBegin;
5489   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
5490   PetscValidPointer(equation_type,2);
5491   *equation_type = ts->equation_type;
5492   PetscFunctionReturn(0);
5493 }
5494 
5495 /*@
5496    TSSetEquationType - Sets the type of the equation that TS is solving.
5497 
5498    Not Collective
5499 
5500    Input Parameter:
5501 +  ts - the TS context
5502 -  equation_type - see TSEquationType
5503 
5504    Level: advanced
5505 
5506 .keywords: TS, equation type
5507 
5508 .seealso: TSGetEquationType(), TSEquationType
5509 @*/
5510 PetscErrorCode  TSSetEquationType(TS ts,TSEquationType equation_type)
5511 {
5512   PetscFunctionBegin;
5513   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
5514   ts->equation_type = equation_type;
5515   PetscFunctionReturn(0);
5516 }
5517 
5518 /*@
5519    TSGetConvergedReason - Gets the reason the TS iteration was stopped.
5520 
5521    Not Collective
5522 
5523    Input Parameter:
5524 .  ts - the TS context
5525 
5526    Output Parameter:
5527 .  reason - negative value indicates diverged, positive value converged, see TSConvergedReason or the
5528             manual pages for the individual convergence tests for complete lists
5529 
5530    Level: beginner
5531 
5532    Notes:
5533    Can only be called after the call to TSSolve() is complete.
5534 
5535 .keywords: TS, nonlinear, set, convergence, test
5536 
5537 .seealso: TSSetConvergenceTest(), TSConvergedReason
5538 @*/
5539 PetscErrorCode  TSGetConvergedReason(TS ts,TSConvergedReason *reason)
5540 {
5541   PetscFunctionBegin;
5542   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
5543   PetscValidPointer(reason,2);
5544   *reason = ts->reason;
5545   PetscFunctionReturn(0);
5546 }
5547 
5548 /*@
5549    TSSetConvergedReason - Sets the reason for handling the convergence of TSSolve.
5550 
5551    Not Collective
5552 
5553    Input Parameter:
5554 +  ts - the TS context
5555 .  reason - negative value indicates diverged, positive value converged, see TSConvergedReason or the
5556             manual pages for the individual convergence tests for complete lists
5557 
5558    Level: advanced
5559 
5560    Notes:
5561    Can only be called during TSSolve() is active.
5562 
5563 .keywords: TS, nonlinear, set, convergence, test
5564 
5565 .seealso: TSConvergedReason
5566 @*/
5567 PetscErrorCode  TSSetConvergedReason(TS ts,TSConvergedReason reason)
5568 {
5569   PetscFunctionBegin;
5570   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
5571   ts->reason = reason;
5572   PetscFunctionReturn(0);
5573 }
5574 
5575 /*@
5576    TSGetSolveTime - Gets the time after a call to TSSolve()
5577 
5578    Not Collective
5579 
5580    Input Parameter:
5581 .  ts - the TS context
5582 
5583    Output Parameter:
5584 .  ftime - the final time. This time corresponds to the final time set with TSSetMaxTime()
5585 
5586    Level: beginner
5587 
5588    Notes:
5589    Can only be called after the call to TSSolve() is complete.
5590 
5591 .keywords: TS, nonlinear, set, convergence, test
5592 
5593 .seealso: TSSetConvergenceTest(), TSConvergedReason
5594 @*/
5595 PetscErrorCode  TSGetSolveTime(TS ts,PetscReal *ftime)
5596 {
5597   PetscFunctionBegin;
5598   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
5599   PetscValidPointer(ftime,2);
5600   *ftime = ts->solvetime;
5601   PetscFunctionReturn(0);
5602 }
5603 
5604 /*@
5605    TSGetSNESIterations - Gets the total number of nonlinear iterations
5606    used by the time integrator.
5607 
5608    Not Collective
5609 
5610    Input Parameter:
5611 .  ts - TS context
5612 
5613    Output Parameter:
5614 .  nits - number of nonlinear iterations
5615 
5616    Notes:
5617    This counter is reset to zero for each successive call to TSSolve().
5618 
5619    Level: intermediate
5620 
5621 .keywords: TS, get, number, nonlinear, iterations
5622 
5623 .seealso:  TSGetKSPIterations()
5624 @*/
5625 PetscErrorCode TSGetSNESIterations(TS ts,PetscInt *nits)
5626 {
5627   PetscFunctionBegin;
5628   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
5629   PetscValidIntPointer(nits,2);
5630   *nits = ts->snes_its;
5631   PetscFunctionReturn(0);
5632 }
5633 
5634 /*@
5635    TSGetKSPIterations - Gets the total number of linear iterations
5636    used by the time integrator.
5637 
5638    Not Collective
5639 
5640    Input Parameter:
5641 .  ts - TS context
5642 
5643    Output Parameter:
5644 .  lits - number of linear iterations
5645 
5646    Notes:
5647    This counter is reset to zero for each successive call to TSSolve().
5648 
5649    Level: intermediate
5650 
5651 .keywords: TS, get, number, linear, iterations
5652 
5653 .seealso:  TSGetSNESIterations(), SNESGetKSPIterations()
5654 @*/
5655 PetscErrorCode TSGetKSPIterations(TS ts,PetscInt *lits)
5656 {
5657   PetscFunctionBegin;
5658   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
5659   PetscValidIntPointer(lits,2);
5660   *lits = ts->ksp_its;
5661   PetscFunctionReturn(0);
5662 }
5663 
5664 /*@
5665    TSGetStepRejections - Gets the total number of rejected steps.
5666 
5667    Not Collective
5668 
5669    Input Parameter:
5670 .  ts - TS context
5671 
5672    Output Parameter:
5673 .  rejects - number of steps rejected
5674 
5675    Notes:
5676    This counter is reset to zero for each successive call to TSSolve().
5677 
5678    Level: intermediate
5679 
5680 .keywords: TS, get, number
5681 
5682 .seealso:  TSGetSNESIterations(), TSGetKSPIterations(), TSSetMaxStepRejections(), TSGetSNESFailures(), TSSetMaxSNESFailures(), TSSetErrorIfStepFails()
5683 @*/
5684 PetscErrorCode TSGetStepRejections(TS ts,PetscInt *rejects)
5685 {
5686   PetscFunctionBegin;
5687   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
5688   PetscValidIntPointer(rejects,2);
5689   *rejects = ts->reject;
5690   PetscFunctionReturn(0);
5691 }
5692 
5693 /*@
5694    TSGetSNESFailures - Gets the total number of failed SNES solves
5695 
5696    Not Collective
5697 
5698    Input Parameter:
5699 .  ts - TS context
5700 
5701    Output Parameter:
5702 .  fails - number of failed nonlinear solves
5703 
5704    Notes:
5705    This counter is reset to zero for each successive call to TSSolve().
5706 
5707    Level: intermediate
5708 
5709 .keywords: TS, get, number
5710 
5711 .seealso:  TSGetSNESIterations(), TSGetKSPIterations(), TSSetMaxStepRejections(), TSGetStepRejections(), TSSetMaxSNESFailures()
5712 @*/
5713 PetscErrorCode TSGetSNESFailures(TS ts,PetscInt *fails)
5714 {
5715   PetscFunctionBegin;
5716   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
5717   PetscValidIntPointer(fails,2);
5718   *fails = ts->num_snes_failures;
5719   PetscFunctionReturn(0);
5720 }
5721 
5722 /*@
5723    TSSetMaxStepRejections - Sets the maximum number of step rejections before a step fails
5724 
5725    Not Collective
5726 
5727    Input Parameter:
5728 +  ts - TS context
5729 -  rejects - maximum number of rejected steps, pass -1 for unlimited
5730 
5731    Notes:
5732    The counter is reset to zero for each step
5733 
5734    Options Database Key:
5735  .  -ts_max_reject - Maximum number of step rejections before a step fails
5736 
5737    Level: intermediate
5738 
5739 .keywords: TS, set, maximum, number
5740 
5741 .seealso:  TSGetSNESIterations(), TSGetKSPIterations(), TSSetMaxSNESFailures(), TSGetStepRejections(), TSGetSNESFailures(), TSSetErrorIfStepFails(), TSGetConvergedReason()
5742 @*/
5743 PetscErrorCode TSSetMaxStepRejections(TS ts,PetscInt rejects)
5744 {
5745   PetscFunctionBegin;
5746   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
5747   ts->max_reject = rejects;
5748   PetscFunctionReturn(0);
5749 }
5750 
5751 /*@
5752    TSSetMaxSNESFailures - Sets the maximum number of failed SNES solves
5753 
5754    Not Collective
5755 
5756    Input Parameter:
5757 +  ts - TS context
5758 -  fails - maximum number of failed nonlinear solves, pass -1 for unlimited
5759 
5760    Notes:
5761    The counter is reset to zero for each successive call to TSSolve().
5762 
5763    Options Database Key:
5764  .  -ts_max_snes_failures - Maximum number of nonlinear solve failures
5765 
5766    Level: intermediate
5767 
5768 .keywords: TS, set, maximum, number
5769 
5770 .seealso:  TSGetSNESIterations(), TSGetKSPIterations(), TSSetMaxStepRejections(), TSGetStepRejections(), TSGetSNESFailures(), SNESGetConvergedReason(), TSGetConvergedReason()
5771 @*/
5772 PetscErrorCode TSSetMaxSNESFailures(TS ts,PetscInt fails)
5773 {
5774   PetscFunctionBegin;
5775   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
5776   ts->max_snes_failures = fails;
5777   PetscFunctionReturn(0);
5778 }
5779 
5780 /*@
5781    TSSetErrorIfStepFails - Error if no step succeeds
5782 
5783    Not Collective
5784 
5785    Input Parameter:
5786 +  ts - TS context
5787 -  err - PETSC_TRUE to error if no step succeeds, PETSC_FALSE to return without failure
5788 
5789    Options Database Key:
5790  .  -ts_error_if_step_fails - Error if no step succeeds
5791 
5792    Level: intermediate
5793 
5794 .keywords: TS, set, error
5795 
5796 .seealso:  TSGetSNESIterations(), TSGetKSPIterations(), TSSetMaxStepRejections(), TSGetStepRejections(), TSGetSNESFailures(), TSSetErrorIfStepFails(), TSGetConvergedReason()
5797 @*/
5798 PetscErrorCode TSSetErrorIfStepFails(TS ts,PetscBool err)
5799 {
5800   PetscFunctionBegin;
5801   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
5802   ts->errorifstepfailed = err;
5803   PetscFunctionReturn(0);
5804 }
5805 
5806 /*@C
5807    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
5808 
5809    Collective on TS
5810 
5811    Input Parameters:
5812 +  ts - the TS context
5813 .  step - current time-step
5814 .  ptime - current time
5815 .  u - current state
5816 -  vf - viewer and its format
5817 
5818    Level: intermediate
5819 
5820 .keywords: TS,  vector, monitor, view
5821 
5822 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView()
5823 @*/
5824 PetscErrorCode  TSMonitorSolution(TS ts,PetscInt step,PetscReal ptime,Vec u,PetscViewerAndFormat *vf)
5825 {
5826   PetscErrorCode ierr;
5827 
5828   PetscFunctionBegin;
5829   ierr = PetscViewerPushFormat(vf->viewer,vf->format);CHKERRQ(ierr);
5830   ierr = VecView(u,vf->viewer);CHKERRQ(ierr);
5831   ierr = PetscViewerPopFormat(vf->viewer);CHKERRQ(ierr);
5832   PetscFunctionReturn(0);
5833 }
5834 
5835 /*@C
5836    TSMonitorSolutionVTK - Monitors progress of the TS solvers by VecView() for the solution at each timestep.
5837 
5838    Collective on TS
5839 
5840    Input Parameters:
5841 +  ts - the TS context
5842 .  step - current time-step
5843 .  ptime - current time
5844 .  u - current state
5845 -  filenametemplate - string containing a format specifier for the integer time step (e.g. %03D)
5846 
5847    Level: intermediate
5848 
5849    Notes:
5850    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.
5851    These are named according to the file name template.
5852 
5853    This function is normally passed as an argument to TSMonitorSet() along with TSMonitorSolutionVTKDestroy().
5854 
5855 .keywords: TS,  vector, monitor, view
5856 
5857 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView()
5858 @*/
5859 PetscErrorCode TSMonitorSolutionVTK(TS ts,PetscInt step,PetscReal ptime,Vec u,void *filenametemplate)
5860 {
5861   PetscErrorCode ierr;
5862   char           filename[PETSC_MAX_PATH_LEN];
5863   PetscViewer    viewer;
5864 
5865   PetscFunctionBegin;
5866   if (step < 0) PetscFunctionReturn(0); /* -1 indicates interpolated solution */
5867   ierr = PetscSNPrintf(filename,sizeof(filename),(const char*)filenametemplate,step);CHKERRQ(ierr);
5868   ierr = PetscViewerVTKOpen(PetscObjectComm((PetscObject)ts),filename,FILE_MODE_WRITE,&viewer);CHKERRQ(ierr);
5869   ierr = VecView(u,viewer);CHKERRQ(ierr);
5870   ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr);
5871   PetscFunctionReturn(0);
5872 }
5873 
5874 /*@C
5875    TSMonitorSolutionVTKDestroy - Destroy context for monitoring
5876 
5877    Collective on TS
5878 
5879    Input Parameters:
5880 .  filenametemplate - string containing a format specifier for the integer time step (e.g. %03D)
5881 
5882    Level: intermediate
5883 
5884    Note:
5885    This function is normally passed to TSMonitorSet() along with TSMonitorSolutionVTK().
5886 
5887 .keywords: TS,  vector, monitor, view
5888 
5889 .seealso: TSMonitorSet(), TSMonitorSolutionVTK()
5890 @*/
5891 PetscErrorCode TSMonitorSolutionVTKDestroy(void *filenametemplate)
5892 {
5893   PetscErrorCode ierr;
5894 
5895   PetscFunctionBegin;
5896   ierr = PetscFree(*(char**)filenametemplate);CHKERRQ(ierr);
5897   PetscFunctionReturn(0);
5898 }
5899 
5900 /*@
5901    TSGetAdapt - Get the adaptive controller context for the current method
5902 
5903    Collective on TS if controller has not been created yet
5904 
5905    Input Arguments:
5906 .  ts - time stepping context
5907 
5908    Output Arguments:
5909 .  adapt - adaptive controller
5910 
5911    Level: intermediate
5912 
5913 .seealso: TSAdapt, TSAdaptSetType(), TSAdaptChoose()
5914 @*/
5915 PetscErrorCode TSGetAdapt(TS ts,TSAdapt *adapt)
5916 {
5917   PetscErrorCode ierr;
5918 
5919   PetscFunctionBegin;
5920   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
5921   PetscValidPointer(adapt,2);
5922   if (!ts->adapt) {
5923     ierr = TSAdaptCreate(PetscObjectComm((PetscObject)ts),&ts->adapt);CHKERRQ(ierr);
5924     ierr = PetscLogObjectParent((PetscObject)ts,(PetscObject)ts->adapt);CHKERRQ(ierr);
5925     ierr = PetscObjectIncrementTabLevel((PetscObject)ts->adapt,(PetscObject)ts,1);CHKERRQ(ierr);
5926   }
5927   *adapt = ts->adapt;
5928   PetscFunctionReturn(0);
5929 }
5930 
5931 /*@
5932    TSSetTolerances - Set tolerances for local truncation error when using adaptive controller
5933 
5934    Logically Collective
5935 
5936    Input Arguments:
5937 +  ts - time integration context
5938 .  atol - scalar absolute tolerances, PETSC_DECIDE to leave current value
5939 .  vatol - vector of absolute tolerances or NULL, used in preference to atol if present
5940 .  rtol - scalar relative tolerances, PETSC_DECIDE to leave current value
5941 -  vrtol - vector of relative tolerances or NULL, used in preference to atol if present
5942 
5943    Options Database keys:
5944 +  -ts_rtol <rtol> - relative tolerance for local truncation error
5945 -  -ts_atol <atol> Absolute tolerance for local truncation error
5946 
5947    Notes:
5948    With PETSc's implicit schemes for DAE problems, the calculation of the local truncation error
5949    (LTE) includes both the differential and the algebraic variables. If one wants the LTE to be
5950    computed only for the differential or the algebraic part then this can be done using the vector of
5951    tolerances vatol. For example, by setting the tolerance vector with the desired tolerance for the
5952    differential part and infinity for the algebraic part, the LTE calculation will include only the
5953    differential variables.
5954 
5955    Level: beginner
5956 
5957 .seealso: TS, TSAdapt, TSVecNormWRMS(), TSGetTolerances()
5958 @*/
5959 PetscErrorCode TSSetTolerances(TS ts,PetscReal atol,Vec vatol,PetscReal rtol,Vec vrtol)
5960 {
5961   PetscErrorCode ierr;
5962 
5963   PetscFunctionBegin;
5964   if (atol != PETSC_DECIDE && atol != PETSC_DEFAULT) ts->atol = atol;
5965   if (vatol) {
5966     ierr = PetscObjectReference((PetscObject)vatol);CHKERRQ(ierr);
5967     ierr = VecDestroy(&ts->vatol);CHKERRQ(ierr);
5968     ts->vatol = vatol;
5969   }
5970   if (rtol != PETSC_DECIDE && rtol != PETSC_DEFAULT) ts->rtol = rtol;
5971   if (vrtol) {
5972     ierr = PetscObjectReference((PetscObject)vrtol);CHKERRQ(ierr);
5973     ierr = VecDestroy(&ts->vrtol);CHKERRQ(ierr);
5974     ts->vrtol = vrtol;
5975   }
5976   PetscFunctionReturn(0);
5977 }
5978 
5979 /*@
5980    TSGetTolerances - Get tolerances for local truncation error when using adaptive controller
5981 
5982    Logically Collective
5983 
5984    Input Arguments:
5985 .  ts - time integration context
5986 
5987    Output Arguments:
5988 +  atol - scalar absolute tolerances, NULL to ignore
5989 .  vatol - vector of absolute tolerances, NULL to ignore
5990 .  rtol - scalar relative tolerances, NULL to ignore
5991 -  vrtol - vector of relative tolerances, NULL to ignore
5992 
5993    Level: beginner
5994 
5995 .seealso: TS, TSAdapt, TSVecNormWRMS(), TSSetTolerances()
5996 @*/
5997 PetscErrorCode TSGetTolerances(TS ts,PetscReal *atol,Vec *vatol,PetscReal *rtol,Vec *vrtol)
5998 {
5999   PetscFunctionBegin;
6000   if (atol)  *atol  = ts->atol;
6001   if (vatol) *vatol = ts->vatol;
6002   if (rtol)  *rtol  = ts->rtol;
6003   if (vrtol) *vrtol = ts->vrtol;
6004   PetscFunctionReturn(0);
6005 }
6006 
6007 /*@
6008    TSErrorWeightedNorm2 - compute a weighted 2-norm of the difference between two state vectors
6009 
6010    Collective on TS
6011 
6012    Input Arguments:
6013 +  ts - time stepping context
6014 .  U - state vector, usually ts->vec_sol
6015 -  Y - state vector to be compared to U
6016 
6017    Output Arguments:
6018 .  norm - weighted norm, a value of 1.0 means that the error matches the tolerances
6019 .  norma - weighted norm based on the absolute tolerance, a value of 1.0 means that the error matches the tolerances
6020 .  normr - weighted norm based on the relative tolerance, a value of 1.0 means that the error matches the tolerances
6021 
6022    Level: developer
6023 
6024 .seealso: TSErrorWeightedNorm(), TSErrorWeightedNormInfinity()
6025 @*/
6026 PetscErrorCode TSErrorWeightedNorm2(TS ts,Vec U,Vec Y,PetscReal *norm,PetscReal *norma,PetscReal *normr)
6027 {
6028   PetscErrorCode    ierr;
6029   PetscInt          i,n,N,rstart;
6030   PetscInt          n_loc,na_loc,nr_loc;
6031   PetscReal         n_glb,na_glb,nr_glb;
6032   const PetscScalar *u,*y;
6033   PetscReal         sum,suma,sumr,gsum,gsuma,gsumr,diff;
6034   PetscReal         tol,tola,tolr;
6035   PetscReal         err_loc[6],err_glb[6];
6036 
6037   PetscFunctionBegin;
6038   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
6039   PetscValidHeaderSpecific(U,VEC_CLASSID,2);
6040   PetscValidHeaderSpecific(Y,VEC_CLASSID,3);
6041   PetscValidType(U,2);
6042   PetscValidType(Y,3);
6043   PetscCheckSameComm(U,2,Y,3);
6044   PetscValidPointer(norm,4);
6045   PetscValidPointer(norma,5);
6046   PetscValidPointer(normr,6);
6047   if (U == Y) SETERRQ(PetscObjectComm((PetscObject)U),PETSC_ERR_ARG_IDN,"U and Y cannot be the same vector");
6048 
6049   ierr = VecGetSize(U,&N);CHKERRQ(ierr);
6050   ierr = VecGetLocalSize(U,&n);CHKERRQ(ierr);
6051   ierr = VecGetOwnershipRange(U,&rstart,NULL);CHKERRQ(ierr);
6052   ierr = VecGetArrayRead(U,&u);CHKERRQ(ierr);
6053   ierr = VecGetArrayRead(Y,&y);CHKERRQ(ierr);
6054   sum  = 0.; n_loc  = 0;
6055   suma = 0.; na_loc = 0;
6056   sumr = 0.; nr_loc = 0;
6057   if (ts->vatol && ts->vrtol) {
6058     const PetscScalar *atol,*rtol;
6059     ierr = VecGetArrayRead(ts->vatol,&atol);CHKERRQ(ierr);
6060     ierr = VecGetArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr);
6061     for (i=0; i<n; i++) {
6062       diff = PetscAbsScalar(y[i] - u[i]);
6063       tola = PetscRealPart(atol[i]);
6064       if(tola>0.){
6065         suma  += PetscSqr(diff/tola);
6066         na_loc++;
6067       }
6068       tolr = PetscRealPart(rtol[i]) * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i]));
6069       if(tolr>0.){
6070         sumr  += PetscSqr(diff/tolr);
6071         nr_loc++;
6072       }
6073       tol=tola+tolr;
6074       if(tol>0.){
6075         sum  += PetscSqr(diff/tol);
6076         n_loc++;
6077       }
6078     }
6079     ierr = VecRestoreArrayRead(ts->vatol,&atol);CHKERRQ(ierr);
6080     ierr = VecRestoreArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr);
6081   } else if (ts->vatol) {       /* vector atol, scalar rtol */
6082     const PetscScalar *atol;
6083     ierr = VecGetArrayRead(ts->vatol,&atol);CHKERRQ(ierr);
6084     for (i=0; i<n; i++) {
6085       diff = PetscAbsScalar(y[i] - u[i]);
6086       tola = PetscRealPart(atol[i]);
6087       if(tola>0.){
6088         suma  += PetscSqr(diff/tola);
6089         na_loc++;
6090       }
6091       tolr = ts->rtol * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i]));
6092       if(tolr>0.){
6093         sumr  += PetscSqr(diff/tolr);
6094         nr_loc++;
6095       }
6096       tol=tola+tolr;
6097       if(tol>0.){
6098         sum  += PetscSqr(diff/tol);
6099         n_loc++;
6100       }
6101     }
6102     ierr = VecRestoreArrayRead(ts->vatol,&atol);CHKERRQ(ierr);
6103   } else if (ts->vrtol) {       /* scalar atol, vector rtol */
6104     const PetscScalar *rtol;
6105     ierr = VecGetArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr);
6106     for (i=0; i<n; i++) {
6107       diff = PetscAbsScalar(y[i] - u[i]);
6108       tola = ts->atol;
6109       if(tola>0.){
6110         suma  += PetscSqr(diff/tola);
6111         na_loc++;
6112       }
6113       tolr = PetscRealPart(rtol[i]) * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i]));
6114       if(tolr>0.){
6115         sumr  += PetscSqr(diff/tolr);
6116         nr_loc++;
6117       }
6118       tol=tola+tolr;
6119       if(tol>0.){
6120         sum  += PetscSqr(diff/tol);
6121         n_loc++;
6122       }
6123     }
6124     ierr = VecRestoreArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr);
6125   } else {                      /* scalar atol, scalar rtol */
6126     for (i=0; i<n; i++) {
6127       diff = PetscAbsScalar(y[i] - u[i]);
6128      tola = ts->atol;
6129       if(tola>0.){
6130         suma  += PetscSqr(diff/tola);
6131         na_loc++;
6132       }
6133       tolr = ts->rtol * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i]));
6134       if(tolr>0.){
6135         sumr  += PetscSqr(diff/tolr);
6136         nr_loc++;
6137       }
6138       tol=tola+tolr;
6139       if(tol>0.){
6140         sum  += PetscSqr(diff/tol);
6141         n_loc++;
6142       }
6143     }
6144   }
6145   ierr = VecRestoreArrayRead(U,&u);CHKERRQ(ierr);
6146   ierr = VecRestoreArrayRead(Y,&y);CHKERRQ(ierr);
6147 
6148   err_loc[0] = sum;
6149   err_loc[1] = suma;
6150   err_loc[2] = sumr;
6151   err_loc[3] = (PetscReal)n_loc;
6152   err_loc[4] = (PetscReal)na_loc;
6153   err_loc[5] = (PetscReal)nr_loc;
6154 
6155   ierr = MPIU_Allreduce(err_loc,err_glb,6,MPIU_REAL,MPIU_SUM,PetscObjectComm((PetscObject)ts));CHKERRQ(ierr);
6156 
6157   gsum   = err_glb[0];
6158   gsuma  = err_glb[1];
6159   gsumr  = err_glb[2];
6160   n_glb  = err_glb[3];
6161   na_glb = err_glb[4];
6162   nr_glb = err_glb[5];
6163 
6164   *norm  = 0.;
6165   if(n_glb>0. ){*norm  = PetscSqrtReal(gsum  / n_glb );}
6166   *norma = 0.;
6167   if(na_glb>0.){*norma = PetscSqrtReal(gsuma / na_glb);}
6168   *normr = 0.;
6169   if(nr_glb>0.){*normr = PetscSqrtReal(gsumr / nr_glb);}
6170 
6171   if (PetscIsInfOrNanScalar(*norm)) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_FP,"Infinite or not-a-number generated in norm");
6172   if (PetscIsInfOrNanScalar(*norma)) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_FP,"Infinite or not-a-number generated in norma");
6173   if (PetscIsInfOrNanScalar(*normr)) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_FP,"Infinite or not-a-number generated in normr");
6174   PetscFunctionReturn(0);
6175 }
6176 
6177 /*@
6178    TSErrorWeightedNormInfinity - compute a weighted infinity-norm of the difference between two state vectors
6179 
6180    Collective on TS
6181 
6182    Input Arguments:
6183 +  ts - time stepping context
6184 .  U - state vector, usually ts->vec_sol
6185 -  Y - state vector to be compared to U
6186 
6187    Output Arguments:
6188 .  norm - weighted norm, a value of 1.0 means that the error matches the tolerances
6189 .  norma - weighted norm based on the absolute tolerance, a value of 1.0 means that the error matches the tolerances
6190 .  normr - weighted norm based on the relative tolerance, a value of 1.0 means that the error matches the tolerances
6191 
6192    Level: developer
6193 
6194 .seealso: TSErrorWeightedNorm(), TSErrorWeightedNorm2()
6195 @*/
6196 PetscErrorCode TSErrorWeightedNormInfinity(TS ts,Vec U,Vec Y,PetscReal *norm,PetscReal *norma,PetscReal *normr)
6197 {
6198   PetscErrorCode    ierr;
6199   PetscInt          i,n,N,rstart;
6200   const PetscScalar *u,*y;
6201   PetscReal         max,gmax,maxa,gmaxa,maxr,gmaxr;
6202   PetscReal         tol,tola,tolr,diff;
6203   PetscReal         err_loc[3],err_glb[3];
6204 
6205   PetscFunctionBegin;
6206   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
6207   PetscValidHeaderSpecific(U,VEC_CLASSID,2);
6208   PetscValidHeaderSpecific(Y,VEC_CLASSID,3);
6209   PetscValidType(U,2);
6210   PetscValidType(Y,3);
6211   PetscCheckSameComm(U,2,Y,3);
6212   PetscValidPointer(norm,4);
6213   PetscValidPointer(norma,5);
6214   PetscValidPointer(normr,6);
6215   if (U == Y) SETERRQ(PetscObjectComm((PetscObject)U),PETSC_ERR_ARG_IDN,"U and Y cannot be the same vector");
6216 
6217   ierr = VecGetSize(U,&N);CHKERRQ(ierr);
6218   ierr = VecGetLocalSize(U,&n);CHKERRQ(ierr);
6219   ierr = VecGetOwnershipRange(U,&rstart,NULL);CHKERRQ(ierr);
6220   ierr = VecGetArrayRead(U,&u);CHKERRQ(ierr);
6221   ierr = VecGetArrayRead(Y,&y);CHKERRQ(ierr);
6222 
6223   max=0.;
6224   maxa=0.;
6225   maxr=0.;
6226 
6227   if (ts->vatol && ts->vrtol) {     /* vector atol, vector rtol */
6228     const PetscScalar *atol,*rtol;
6229     ierr = VecGetArrayRead(ts->vatol,&atol);CHKERRQ(ierr);
6230     ierr = VecGetArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr);
6231 
6232     for (i=0; i<n; i++) {
6233       diff = PetscAbsScalar(y[i] - u[i]);
6234       tola = PetscRealPart(atol[i]);
6235       tolr = PetscRealPart(rtol[i]) * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i]));
6236       tol  = tola+tolr;
6237       if(tola>0.){
6238         maxa = PetscMax(maxa,diff / tola);
6239       }
6240       if(tolr>0.){
6241         maxr = PetscMax(maxr,diff / tolr);
6242       }
6243       if(tol>0.){
6244         max = PetscMax(max,diff / tol);
6245       }
6246     }
6247     ierr = VecRestoreArrayRead(ts->vatol,&atol);CHKERRQ(ierr);
6248     ierr = VecRestoreArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr);
6249   } else if (ts->vatol) {       /* vector atol, scalar rtol */
6250     const PetscScalar *atol;
6251     ierr = VecGetArrayRead(ts->vatol,&atol);CHKERRQ(ierr);
6252     for (i=0; i<n; i++) {
6253       diff = PetscAbsScalar(y[i] - u[i]);
6254       tola = PetscRealPart(atol[i]);
6255       tolr = ts->rtol  * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i]));
6256       tol  = tola+tolr;
6257       if(tola>0.){
6258         maxa = PetscMax(maxa,diff / tola);
6259       }
6260       if(tolr>0.){
6261         maxr = PetscMax(maxr,diff / tolr);
6262       }
6263       if(tol>0.){
6264         max = PetscMax(max,diff / tol);
6265       }
6266     }
6267     ierr = VecRestoreArrayRead(ts->vatol,&atol);CHKERRQ(ierr);
6268   } else if (ts->vrtol) {       /* scalar atol, vector rtol */
6269     const PetscScalar *rtol;
6270     ierr = VecGetArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr);
6271 
6272     for (i=0; i<n; i++) {
6273       diff = PetscAbsScalar(y[i] - u[i]);
6274       tola = ts->atol;
6275       tolr = PetscRealPart(rtol[i]) * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i]));
6276       tol  = tola+tolr;
6277       if(tola>0.){
6278         maxa = PetscMax(maxa,diff / tola);
6279       }
6280       if(tolr>0.){
6281         maxr = PetscMax(maxr,diff / tolr);
6282       }
6283       if(tol>0.){
6284         max = PetscMax(max,diff / tol);
6285       }
6286     }
6287     ierr = VecRestoreArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr);
6288   } else {                      /* scalar atol, scalar rtol */
6289 
6290     for (i=0; i<n; i++) {
6291       diff = PetscAbsScalar(y[i] - u[i]);
6292       tola = ts->atol;
6293       tolr = ts->rtol * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i]));
6294       tol  = tola+tolr;
6295       if(tola>0.){
6296         maxa = PetscMax(maxa,diff / tola);
6297       }
6298       if(tolr>0.){
6299         maxr = PetscMax(maxr,diff / tolr);
6300       }
6301       if(tol>0.){
6302         max = PetscMax(max,diff / tol);
6303       }
6304     }
6305   }
6306   ierr = VecRestoreArrayRead(U,&u);CHKERRQ(ierr);
6307   ierr = VecRestoreArrayRead(Y,&y);CHKERRQ(ierr);
6308   err_loc[0] = max;
6309   err_loc[1] = maxa;
6310   err_loc[2] = maxr;
6311   ierr  = MPIU_Allreduce(err_loc,err_glb,3,MPIU_REAL,MPIU_MAX,PetscObjectComm((PetscObject)ts));CHKERRQ(ierr);
6312   gmax   = err_glb[0];
6313   gmaxa  = err_glb[1];
6314   gmaxr  = err_glb[2];
6315 
6316   *norm = gmax;
6317   *norma = gmaxa;
6318   *normr = gmaxr;
6319   if (PetscIsInfOrNanScalar(*norm)) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_FP,"Infinite or not-a-number generated in norm");
6320     if (PetscIsInfOrNanScalar(*norma)) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_FP,"Infinite or not-a-number generated in norma");
6321     if (PetscIsInfOrNanScalar(*normr)) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_FP,"Infinite or not-a-number generated in normr");
6322   PetscFunctionReturn(0);
6323 }
6324 
6325 /*@
6326    TSErrorWeightedNorm - compute a weighted norm of the difference between two state vectors based on supplied absolute and relative tolerances
6327 
6328    Collective on TS
6329 
6330    Input Arguments:
6331 +  ts - time stepping context
6332 .  U - state vector, usually ts->vec_sol
6333 .  Y - state vector to be compared to U
6334 -  wnormtype - norm type, either NORM_2 or NORM_INFINITY
6335 
6336    Output Arguments:
6337 .  norm  - weighted norm, a value of 1.0 achieves a balance between absolute and relative tolerances
6338 .  norma - weighted norm, a value of 1.0 means that the error meets the absolute tolerance set by the user
6339 .  normr - weighted norm, a value of 1.0 means that the error meets the relative tolerance set by the user
6340 
6341    Options Database Keys:
6342 .  -ts_adapt_wnormtype <wnormtype> - 2, INFINITY
6343 
6344    Level: developer
6345 
6346 .seealso: TSErrorWeightedNormInfinity(), TSErrorWeightedNorm2(), TSErrorWeightedENorm
6347 @*/
6348 PetscErrorCode TSErrorWeightedNorm(TS ts,Vec U,Vec Y,NormType wnormtype,PetscReal *norm,PetscReal *norma,PetscReal *normr)
6349 {
6350   PetscErrorCode ierr;
6351 
6352   PetscFunctionBegin;
6353   if (wnormtype == NORM_2) {
6354     ierr = TSErrorWeightedNorm2(ts,U,Y,norm,norma,normr);CHKERRQ(ierr);
6355   } else if(wnormtype == NORM_INFINITY) {
6356     ierr = TSErrorWeightedNormInfinity(ts,U,Y,norm,norma,normr);CHKERRQ(ierr);
6357   } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"No support for norm type %s",NormTypes[wnormtype]);
6358   PetscFunctionReturn(0);
6359 }
6360 
6361 
6362 /*@
6363    TSErrorWeightedENorm2 - compute a weighted 2 error norm based on supplied absolute and relative tolerances
6364 
6365    Collective on TS
6366 
6367    Input Arguments:
6368 +  ts - time stepping context
6369 .  E - error vector
6370 .  U - state vector, usually ts->vec_sol
6371 -  Y - state vector, previous time step
6372 
6373    Output Arguments:
6374 .  norm - weighted norm, a value of 1.0 means that the error matches the tolerances
6375 .  norma - weighted norm based on the absolute tolerance, a value of 1.0 means that the error matches the tolerances
6376 .  normr - weighted norm based on the relative tolerance, a value of 1.0 means that the error matches the tolerances
6377 
6378    Level: developer
6379 
6380 .seealso: TSErrorWeightedENorm(), TSErrorWeightedENormInfinity()
6381 @*/
6382 PetscErrorCode TSErrorWeightedENorm2(TS ts,Vec E,Vec U,Vec Y,PetscReal *norm,PetscReal *norma,PetscReal *normr)
6383 {
6384   PetscErrorCode    ierr;
6385   PetscInt          i,n,N,rstart;
6386   PetscInt          n_loc,na_loc,nr_loc;
6387   PetscReal         n_glb,na_glb,nr_glb;
6388   const PetscScalar *e,*u,*y;
6389   PetscReal         err,sum,suma,sumr,gsum,gsuma,gsumr;
6390   PetscReal         tol,tola,tolr;
6391   PetscReal         err_loc[6],err_glb[6];
6392 
6393   PetscFunctionBegin;
6394   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
6395   PetscValidHeaderSpecific(E,VEC_CLASSID,2);
6396   PetscValidHeaderSpecific(U,VEC_CLASSID,3);
6397   PetscValidHeaderSpecific(Y,VEC_CLASSID,4);
6398   PetscValidType(E,2);
6399   PetscValidType(U,3);
6400   PetscValidType(Y,4);
6401   PetscCheckSameComm(E,2,U,3);
6402   PetscCheckSameComm(U,2,Y,3);
6403   PetscValidPointer(norm,5);
6404   PetscValidPointer(norma,6);
6405   PetscValidPointer(normr,7);
6406 
6407   ierr = VecGetSize(E,&N);CHKERRQ(ierr);
6408   ierr = VecGetLocalSize(E,&n);CHKERRQ(ierr);
6409   ierr = VecGetOwnershipRange(E,&rstart,NULL);CHKERRQ(ierr);
6410   ierr = VecGetArrayRead(E,&e);CHKERRQ(ierr);
6411   ierr = VecGetArrayRead(U,&u);CHKERRQ(ierr);
6412   ierr = VecGetArrayRead(Y,&y);CHKERRQ(ierr);
6413   sum  = 0.; n_loc  = 0;
6414   suma = 0.; na_loc = 0;
6415   sumr = 0.; nr_loc = 0;
6416   if (ts->vatol && ts->vrtol) {
6417     const PetscScalar *atol,*rtol;
6418     ierr = VecGetArrayRead(ts->vatol,&atol);CHKERRQ(ierr);
6419     ierr = VecGetArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr);
6420     for (i=0; i<n; i++) {
6421       err = PetscAbsScalar(e[i]);
6422       tola = PetscRealPart(atol[i]);
6423       if(tola>0.){
6424         suma  += PetscSqr(err/tola);
6425         na_loc++;
6426       }
6427       tolr = PetscRealPart(rtol[i]) * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i]));
6428       if(tolr>0.){
6429         sumr  += PetscSqr(err/tolr);
6430         nr_loc++;
6431       }
6432       tol=tola+tolr;
6433       if(tol>0.){
6434         sum  += PetscSqr(err/tol);
6435         n_loc++;
6436       }
6437     }
6438     ierr = VecRestoreArrayRead(ts->vatol,&atol);CHKERRQ(ierr);
6439     ierr = VecRestoreArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr);
6440   } else if (ts->vatol) {       /* vector atol, scalar rtol */
6441     const PetscScalar *atol;
6442     ierr = VecGetArrayRead(ts->vatol,&atol);CHKERRQ(ierr);
6443     for (i=0; i<n; i++) {
6444       err = PetscAbsScalar(e[i]);
6445       tola = PetscRealPart(atol[i]);
6446       if(tola>0.){
6447         suma  += PetscSqr(err/tola);
6448         na_loc++;
6449       }
6450       tolr = ts->rtol * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i]));
6451       if(tolr>0.){
6452         sumr  += PetscSqr(err/tolr);
6453         nr_loc++;
6454       }
6455       tol=tola+tolr;
6456       if(tol>0.){
6457         sum  += PetscSqr(err/tol);
6458         n_loc++;
6459       }
6460     }
6461     ierr = VecRestoreArrayRead(ts->vatol,&atol);CHKERRQ(ierr);
6462   } else if (ts->vrtol) {       /* scalar atol, vector rtol */
6463     const PetscScalar *rtol;
6464     ierr = VecGetArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr);
6465     for (i=0; i<n; i++) {
6466       err = PetscAbsScalar(e[i]);
6467       tola = ts->atol;
6468       if(tola>0.){
6469         suma  += PetscSqr(err/tola);
6470         na_loc++;
6471       }
6472       tolr = PetscRealPart(rtol[i]) * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i]));
6473       if(tolr>0.){
6474         sumr  += PetscSqr(err/tolr);
6475         nr_loc++;
6476       }
6477       tol=tola+tolr;
6478       if(tol>0.){
6479         sum  += PetscSqr(err/tol);
6480         n_loc++;
6481       }
6482     }
6483     ierr = VecRestoreArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr);
6484   } else {                      /* scalar atol, scalar rtol */
6485     for (i=0; i<n; i++) {
6486       err = PetscAbsScalar(e[i]);
6487      tola = ts->atol;
6488       if(tola>0.){
6489         suma  += PetscSqr(err/tola);
6490         na_loc++;
6491       }
6492       tolr = ts->rtol * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i]));
6493       if(tolr>0.){
6494         sumr  += PetscSqr(err/tolr);
6495         nr_loc++;
6496       }
6497       tol=tola+tolr;
6498       if(tol>0.){
6499         sum  += PetscSqr(err/tol);
6500         n_loc++;
6501       }
6502     }
6503   }
6504   ierr = VecRestoreArrayRead(E,&e);CHKERRQ(ierr);
6505   ierr = VecRestoreArrayRead(U,&u);CHKERRQ(ierr);
6506   ierr = VecRestoreArrayRead(Y,&y);CHKERRQ(ierr);
6507 
6508   err_loc[0] = sum;
6509   err_loc[1] = suma;
6510   err_loc[2] = sumr;
6511   err_loc[3] = (PetscReal)n_loc;
6512   err_loc[4] = (PetscReal)na_loc;
6513   err_loc[5] = (PetscReal)nr_loc;
6514 
6515   ierr = MPIU_Allreduce(err_loc,err_glb,6,MPIU_REAL,MPIU_SUM,PetscObjectComm((PetscObject)ts));CHKERRQ(ierr);
6516 
6517   gsum   = err_glb[0];
6518   gsuma  = err_glb[1];
6519   gsumr  = err_glb[2];
6520   n_glb  = err_glb[3];
6521   na_glb = err_glb[4];
6522   nr_glb = err_glb[5];
6523 
6524   *norm  = 0.;
6525   if(n_glb>0. ){*norm  = PetscSqrtReal(gsum  / n_glb );}
6526   *norma = 0.;
6527   if(na_glb>0.){*norma = PetscSqrtReal(gsuma / na_glb);}
6528   *normr = 0.;
6529   if(nr_glb>0.){*normr = PetscSqrtReal(gsumr / nr_glb);}
6530 
6531   if (PetscIsInfOrNanScalar(*norm)) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_FP,"Infinite or not-a-number generated in norm");
6532   if (PetscIsInfOrNanScalar(*norma)) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_FP,"Infinite or not-a-number generated in norma");
6533   if (PetscIsInfOrNanScalar(*normr)) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_FP,"Infinite or not-a-number generated in normr");
6534   PetscFunctionReturn(0);
6535 }
6536 
6537 /*@
6538    TSErrorWeightedENormInfinity - compute a weighted infinity error norm based on supplied absolute and relative tolerances
6539    Collective on TS
6540 
6541    Input Arguments:
6542 +  ts - time stepping context
6543 .  E - error vector
6544 .  U - state vector, usually ts->vec_sol
6545 -  Y - state vector, previous time step
6546 
6547    Output Arguments:
6548 .  norm - weighted norm, a value of 1.0 means that the error matches the tolerances
6549 .  norma - weighted norm based on the absolute tolerance, a value of 1.0 means that the error matches the tolerances
6550 .  normr - weighted norm based on the relative tolerance, a value of 1.0 means that the error matches the tolerances
6551 
6552    Level: developer
6553 
6554 .seealso: TSErrorWeightedENorm(), TSErrorWeightedENorm2()
6555 @*/
6556 PetscErrorCode TSErrorWeightedENormInfinity(TS ts,Vec E,Vec U,Vec Y,PetscReal *norm,PetscReal *norma,PetscReal *normr)
6557 {
6558   PetscErrorCode    ierr;
6559   PetscInt          i,n,N,rstart;
6560   const PetscScalar *e,*u,*y;
6561   PetscReal         err,max,gmax,maxa,gmaxa,maxr,gmaxr;
6562   PetscReal         tol,tola,tolr;
6563   PetscReal         err_loc[3],err_glb[3];
6564 
6565   PetscFunctionBegin;
6566   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
6567   PetscValidHeaderSpecific(E,VEC_CLASSID,2);
6568   PetscValidHeaderSpecific(U,VEC_CLASSID,3);
6569   PetscValidHeaderSpecific(Y,VEC_CLASSID,4);
6570   PetscValidType(E,2);
6571   PetscValidType(U,3);
6572   PetscValidType(Y,4);
6573   PetscCheckSameComm(E,2,U,3);
6574   PetscCheckSameComm(U,2,Y,3);
6575   PetscValidPointer(norm,5);
6576   PetscValidPointer(norma,6);
6577   PetscValidPointer(normr,7);
6578 
6579   ierr = VecGetSize(E,&N);CHKERRQ(ierr);
6580   ierr = VecGetLocalSize(E,&n);CHKERRQ(ierr);
6581   ierr = VecGetOwnershipRange(E,&rstart,NULL);CHKERRQ(ierr);
6582   ierr = VecGetArrayRead(E,&e);CHKERRQ(ierr);
6583   ierr = VecGetArrayRead(U,&u);CHKERRQ(ierr);
6584   ierr = VecGetArrayRead(Y,&y);CHKERRQ(ierr);
6585 
6586   max=0.;
6587   maxa=0.;
6588   maxr=0.;
6589 
6590   if (ts->vatol && ts->vrtol) {     /* vector atol, vector rtol */
6591     const PetscScalar *atol,*rtol;
6592     ierr = VecGetArrayRead(ts->vatol,&atol);CHKERRQ(ierr);
6593     ierr = VecGetArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr);
6594 
6595     for (i=0; i<n; i++) {
6596       err = PetscAbsScalar(e[i]);
6597       tola = PetscRealPart(atol[i]);
6598       tolr = PetscRealPart(rtol[i]) * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i]));
6599       tol  = tola+tolr;
6600       if(tola>0.){
6601         maxa = PetscMax(maxa,err / tola);
6602       }
6603       if(tolr>0.){
6604         maxr = PetscMax(maxr,err / tolr);
6605       }
6606       if(tol>0.){
6607         max = PetscMax(max,err / tol);
6608       }
6609     }
6610     ierr = VecRestoreArrayRead(ts->vatol,&atol);CHKERRQ(ierr);
6611     ierr = VecRestoreArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr);
6612   } else if (ts->vatol) {       /* vector atol, scalar rtol */
6613     const PetscScalar *atol;
6614     ierr = VecGetArrayRead(ts->vatol,&atol);CHKERRQ(ierr);
6615     for (i=0; i<n; i++) {
6616       err = PetscAbsScalar(e[i]);
6617       tola = PetscRealPart(atol[i]);
6618       tolr = ts->rtol  * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i]));
6619       tol  = tola+tolr;
6620       if(tola>0.){
6621         maxa = PetscMax(maxa,err / tola);
6622       }
6623       if(tolr>0.){
6624         maxr = PetscMax(maxr,err / tolr);
6625       }
6626       if(tol>0.){
6627         max = PetscMax(max,err / tol);
6628       }
6629     }
6630     ierr = VecRestoreArrayRead(ts->vatol,&atol);CHKERRQ(ierr);
6631   } else if (ts->vrtol) {       /* scalar atol, vector rtol */
6632     const PetscScalar *rtol;
6633     ierr = VecGetArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr);
6634 
6635     for (i=0; i<n; i++) {
6636       err = PetscAbsScalar(e[i]);
6637       tola = ts->atol;
6638       tolr = PetscRealPart(rtol[i]) * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i]));
6639       tol  = tola+tolr;
6640       if(tola>0.){
6641         maxa = PetscMax(maxa,err / tola);
6642       }
6643       if(tolr>0.){
6644         maxr = PetscMax(maxr,err / tolr);
6645       }
6646       if(tol>0.){
6647         max = PetscMax(max,err / tol);
6648       }
6649     }
6650     ierr = VecRestoreArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr);
6651   } else {                      /* scalar atol, scalar rtol */
6652 
6653     for (i=0; i<n; i++) {
6654       err = PetscAbsScalar(e[i]);
6655       tola = ts->atol;
6656       tolr = ts->rtol * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i]));
6657       tol  = tola+tolr;
6658       if(tola>0.){
6659         maxa = PetscMax(maxa,err / tola);
6660       }
6661       if(tolr>0.){
6662         maxr = PetscMax(maxr,err / tolr);
6663       }
6664       if(tol>0.){
6665         max = PetscMax(max,err / tol);
6666       }
6667     }
6668   }
6669   ierr = VecRestoreArrayRead(E,&e);CHKERRQ(ierr);
6670   ierr = VecRestoreArrayRead(U,&u);CHKERRQ(ierr);
6671   ierr = VecRestoreArrayRead(Y,&y);CHKERRQ(ierr);
6672   err_loc[0] = max;
6673   err_loc[1] = maxa;
6674   err_loc[2] = maxr;
6675   ierr  = MPIU_Allreduce(err_loc,err_glb,3,MPIU_REAL,MPIU_MAX,PetscObjectComm((PetscObject)ts));CHKERRQ(ierr);
6676   gmax   = err_glb[0];
6677   gmaxa  = err_glb[1];
6678   gmaxr  = err_glb[2];
6679 
6680   *norm = gmax;
6681   *norma = gmaxa;
6682   *normr = gmaxr;
6683   if (PetscIsInfOrNanScalar(*norm)) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_FP,"Infinite or not-a-number generated in norm");
6684     if (PetscIsInfOrNanScalar(*norma)) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_FP,"Infinite or not-a-number generated in norma");
6685     if (PetscIsInfOrNanScalar(*normr)) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_FP,"Infinite or not-a-number generated in normr");
6686   PetscFunctionReturn(0);
6687 }
6688 
6689 /*@
6690    TSErrorWeightedENorm - compute a weighted error norm based on supplied absolute and relative tolerances
6691 
6692    Collective on TS
6693 
6694    Input Arguments:
6695 +  ts - time stepping context
6696 .  E - error vector
6697 .  U - state vector, usually ts->vec_sol
6698 .  Y - state vector, previous time step
6699 -  wnormtype - norm type, either NORM_2 or NORM_INFINITY
6700 
6701    Output Arguments:
6702 .  norm  - weighted norm, a value of 1.0 achieves a balance between absolute and relative tolerances
6703 .  norma - weighted norm, a value of 1.0 means that the error meets the absolute tolerance set by the user
6704 .  normr - weighted norm, a value of 1.0 means that the error meets the relative tolerance set by the user
6705 
6706    Options Database Keys:
6707 .  -ts_adapt_wnormtype <wnormtype> - 2, INFINITY
6708 
6709    Level: developer
6710 
6711 .seealso: TSErrorWeightedENormInfinity(), TSErrorWeightedENorm2(), TSErrorWeightedNormInfinity(), TSErrorWeightedNorm2()
6712 @*/
6713 PetscErrorCode TSErrorWeightedENorm(TS ts,Vec E,Vec U,Vec Y,NormType wnormtype,PetscReal *norm,PetscReal *norma,PetscReal *normr)
6714 {
6715   PetscErrorCode ierr;
6716 
6717   PetscFunctionBegin;
6718   if (wnormtype == NORM_2) {
6719     ierr = TSErrorWeightedENorm2(ts,E,U,Y,norm,norma,normr);CHKERRQ(ierr);
6720   } else if(wnormtype == NORM_INFINITY) {
6721     ierr = TSErrorWeightedENormInfinity(ts,E,U,Y,norm,norma,normr);CHKERRQ(ierr);
6722   } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"No support for norm type %s",NormTypes[wnormtype]);
6723   PetscFunctionReturn(0);
6724 }
6725 
6726 
6727 /*@
6728    TSSetCFLTimeLocal - Set the local CFL constraint relative to forward Euler
6729 
6730    Logically Collective on TS
6731 
6732    Input Arguments:
6733 +  ts - time stepping context
6734 -  cfltime - maximum stable time step if using forward Euler (value can be different on each process)
6735 
6736    Note:
6737    After calling this function, the global CFL time can be obtained by calling TSGetCFLTime()
6738 
6739    Level: intermediate
6740 
6741 .seealso: TSGetCFLTime(), TSADAPTCFL
6742 @*/
6743 PetscErrorCode TSSetCFLTimeLocal(TS ts,PetscReal cfltime)
6744 {
6745   PetscFunctionBegin;
6746   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
6747   ts->cfltime_local = cfltime;
6748   ts->cfltime       = -1.;
6749   PetscFunctionReturn(0);
6750 }
6751 
6752 /*@
6753    TSGetCFLTime - Get the maximum stable time step according to CFL criteria applied to forward Euler
6754 
6755    Collective on TS
6756 
6757    Input Arguments:
6758 .  ts - time stepping context
6759 
6760    Output Arguments:
6761 .  cfltime - maximum stable time step for forward Euler
6762 
6763    Level: advanced
6764 
6765 .seealso: TSSetCFLTimeLocal()
6766 @*/
6767 PetscErrorCode TSGetCFLTime(TS ts,PetscReal *cfltime)
6768 {
6769   PetscErrorCode ierr;
6770 
6771   PetscFunctionBegin;
6772   if (ts->cfltime < 0) {
6773     ierr = MPIU_Allreduce(&ts->cfltime_local,&ts->cfltime,1,MPIU_REAL,MPIU_MIN,PetscObjectComm((PetscObject)ts));CHKERRQ(ierr);
6774   }
6775   *cfltime = ts->cfltime;
6776   PetscFunctionReturn(0);
6777 }
6778 
6779 /*@
6780    TSVISetVariableBounds - Sets the lower and upper bounds for the solution vector. xl <= x <= xu
6781 
6782    Input Parameters:
6783 .  ts   - the TS context.
6784 .  xl   - lower bound.
6785 .  xu   - upper bound.
6786 
6787    Notes:
6788    If this routine is not called then the lower and upper bounds are set to
6789    PETSC_NINFINITY and PETSC_INFINITY respectively during SNESSetUp().
6790 
6791    Level: advanced
6792 
6793 @*/
6794 PetscErrorCode TSVISetVariableBounds(TS ts, Vec xl, Vec xu)
6795 {
6796   PetscErrorCode ierr;
6797   SNES           snes;
6798 
6799   PetscFunctionBegin;
6800   ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr);
6801   ierr = SNESVISetVariableBounds(snes,xl,xu);CHKERRQ(ierr);
6802   PetscFunctionReturn(0);
6803 }
6804 
6805 #if defined(PETSC_HAVE_MATLAB_ENGINE)
6806 #include <mex.h>
6807 
6808 typedef struct {char *funcname; mxArray *ctx;} TSMatlabContext;
6809 
6810 /*
6811    TSComputeFunction_Matlab - Calls the function that has been set with
6812                          TSSetFunctionMatlab().
6813 
6814    Collective on TS
6815 
6816    Input Parameters:
6817 +  snes - the TS context
6818 -  u - input vector
6819 
6820    Output Parameter:
6821 .  y - function vector, as set by TSSetFunction()
6822 
6823    Notes:
6824    TSComputeFunction() is typically used within nonlinear solvers
6825    implementations, so most users would not generally call this routine
6826    themselves.
6827 
6828    Level: developer
6829 
6830 .keywords: TS, nonlinear, compute, function
6831 
6832 .seealso: TSSetFunction(), TSGetFunction()
6833 */
6834 PetscErrorCode  TSComputeFunction_Matlab(TS snes,PetscReal time,Vec u,Vec udot,Vec y, void *ctx)
6835 {
6836   PetscErrorCode  ierr;
6837   TSMatlabContext *sctx = (TSMatlabContext*)ctx;
6838   int             nlhs  = 1,nrhs = 7;
6839   mxArray         *plhs[1],*prhs[7];
6840   long long int   lx = 0,lxdot = 0,ly = 0,ls = 0;
6841 
6842   PetscFunctionBegin;
6843   PetscValidHeaderSpecific(snes,TS_CLASSID,1);
6844   PetscValidHeaderSpecific(u,VEC_CLASSID,3);
6845   PetscValidHeaderSpecific(udot,VEC_CLASSID,4);
6846   PetscValidHeaderSpecific(y,VEC_CLASSID,5);
6847   PetscCheckSameComm(snes,1,u,3);
6848   PetscCheckSameComm(snes,1,y,5);
6849 
6850   ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr);
6851   ierr = PetscMemcpy(&lx,&u,sizeof(u));CHKERRQ(ierr);
6852   ierr = PetscMemcpy(&lxdot,&udot,sizeof(udot));CHKERRQ(ierr);
6853   ierr = PetscMemcpy(&ly,&y,sizeof(u));CHKERRQ(ierr);
6854 
6855   prhs[0] =  mxCreateDoubleScalar((double)ls);
6856   prhs[1] =  mxCreateDoubleScalar(time);
6857   prhs[2] =  mxCreateDoubleScalar((double)lx);
6858   prhs[3] =  mxCreateDoubleScalar((double)lxdot);
6859   prhs[4] =  mxCreateDoubleScalar((double)ly);
6860   prhs[5] =  mxCreateString(sctx->funcname);
6861   prhs[6] =  sctx->ctx;
6862   ierr    =  mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscTSComputeFunctionInternal");CHKERRQ(ierr);
6863   ierr    =  mxGetScalar(plhs[0]);CHKERRQ(ierr);
6864   mxDestroyArray(prhs[0]);
6865   mxDestroyArray(prhs[1]);
6866   mxDestroyArray(prhs[2]);
6867   mxDestroyArray(prhs[3]);
6868   mxDestroyArray(prhs[4]);
6869   mxDestroyArray(prhs[5]);
6870   mxDestroyArray(plhs[0]);
6871   PetscFunctionReturn(0);
6872 }
6873 
6874 /*
6875    TSSetFunctionMatlab - Sets the function evaluation routine and function
6876    vector for use by the TS routines in solving ODEs
6877    equations from MATLAB. Here the function is a string containing the name of a MATLAB function
6878 
6879    Logically Collective on TS
6880 
6881    Input Parameters:
6882 +  ts - the TS context
6883 -  func - function evaluation routine
6884 
6885    Calling sequence of func:
6886 $    func (TS ts,PetscReal time,Vec u,Vec udot,Vec f,void *ctx);
6887 
6888    Level: beginner
6889 
6890 .keywords: TS, nonlinear, set, function
6891 
6892 .seealso: TSGetFunction(), TSComputeFunction(), TSSetJacobian(), TSSetFunction()
6893 */
6894 PetscErrorCode  TSSetFunctionMatlab(TS ts,const char *func,mxArray *ctx)
6895 {
6896   PetscErrorCode  ierr;
6897   TSMatlabContext *sctx;
6898 
6899   PetscFunctionBegin;
6900   /* currently sctx is memory bleed */
6901   ierr = PetscNew(&sctx);CHKERRQ(ierr);
6902   ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr);
6903   /*
6904      This should work, but it doesn't
6905   sctx->ctx = ctx;
6906   mexMakeArrayPersistent(sctx->ctx);
6907   */
6908   sctx->ctx = mxDuplicateArray(ctx);
6909 
6910   ierr = TSSetIFunction(ts,NULL,TSComputeFunction_Matlab,sctx);CHKERRQ(ierr);
6911   PetscFunctionReturn(0);
6912 }
6913 
6914 /*
6915    TSComputeJacobian_Matlab - Calls the function that has been set with
6916                          TSSetJacobianMatlab().
6917 
6918    Collective on TS
6919 
6920    Input Parameters:
6921 +  ts - the TS context
6922 .  u - input vector
6923 .  A, B - the matrices
6924 -  ctx - user context
6925 
6926    Level: developer
6927 
6928 .keywords: TS, nonlinear, compute, function
6929 
6930 .seealso: TSSetFunction(), TSGetFunction()
6931 @*/
6932 PetscErrorCode  TSComputeJacobian_Matlab(TS ts,PetscReal time,Vec u,Vec udot,PetscReal shift,Mat A,Mat B,void *ctx)
6933 {
6934   PetscErrorCode  ierr;
6935   TSMatlabContext *sctx = (TSMatlabContext*)ctx;
6936   int             nlhs  = 2,nrhs = 9;
6937   mxArray         *plhs[2],*prhs[9];
6938   long long int   lx = 0,lxdot = 0,lA = 0,ls = 0, lB = 0;
6939 
6940   PetscFunctionBegin;
6941   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
6942   PetscValidHeaderSpecific(u,VEC_CLASSID,3);
6943 
6944   /* call Matlab function in ctx with arguments u and y */
6945 
6946   ierr = PetscMemcpy(&ls,&ts,sizeof(ts));CHKERRQ(ierr);
6947   ierr = PetscMemcpy(&lx,&u,sizeof(u));CHKERRQ(ierr);
6948   ierr = PetscMemcpy(&lxdot,&udot,sizeof(u));CHKERRQ(ierr);
6949   ierr = PetscMemcpy(&lA,A,sizeof(u));CHKERRQ(ierr);
6950   ierr = PetscMemcpy(&lB,B,sizeof(u));CHKERRQ(ierr);
6951 
6952   prhs[0] =  mxCreateDoubleScalar((double)ls);
6953   prhs[1] =  mxCreateDoubleScalar((double)time);
6954   prhs[2] =  mxCreateDoubleScalar((double)lx);
6955   prhs[3] =  mxCreateDoubleScalar((double)lxdot);
6956   prhs[4] =  mxCreateDoubleScalar((double)shift);
6957   prhs[5] =  mxCreateDoubleScalar((double)lA);
6958   prhs[6] =  mxCreateDoubleScalar((double)lB);
6959   prhs[7] =  mxCreateString(sctx->funcname);
6960   prhs[8] =  sctx->ctx;
6961   ierr    =  mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscTSComputeJacobianInternal");CHKERRQ(ierr);
6962   ierr    =  mxGetScalar(plhs[0]);CHKERRQ(ierr);
6963   mxDestroyArray(prhs[0]);
6964   mxDestroyArray(prhs[1]);
6965   mxDestroyArray(prhs[2]);
6966   mxDestroyArray(prhs[3]);
6967   mxDestroyArray(prhs[4]);
6968   mxDestroyArray(prhs[5]);
6969   mxDestroyArray(prhs[6]);
6970   mxDestroyArray(prhs[7]);
6971   mxDestroyArray(plhs[0]);
6972   mxDestroyArray(plhs[1]);
6973   PetscFunctionReturn(0);
6974 }
6975 
6976 /*
6977    TSSetJacobianMatlab - Sets the Jacobian function evaluation routine and two empty Jacobian matrices
6978    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
6979 
6980    Logically Collective on TS
6981 
6982    Input Parameters:
6983 +  ts - the TS context
6984 .  A,B - Jacobian matrices
6985 .  func - function evaluation routine
6986 -  ctx - user context
6987 
6988    Calling sequence of func:
6989 $    flag = func (TS ts,PetscReal time,Vec u,Vec udot,Mat A,Mat B,void *ctx);
6990 
6991    Level: developer
6992 
6993 .keywords: TS, nonlinear, set, function
6994 
6995 .seealso: TSGetFunction(), TSComputeFunction(), TSSetJacobian(), TSSetFunction()
6996 */
6997 PetscErrorCode  TSSetJacobianMatlab(TS ts,Mat A,Mat B,const char *func,mxArray *ctx)
6998 {
6999   PetscErrorCode  ierr;
7000   TSMatlabContext *sctx;
7001 
7002   PetscFunctionBegin;
7003   /* currently sctx is memory bleed */
7004   ierr = PetscNew(&sctx);CHKERRQ(ierr);
7005   ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr);
7006   /*
7007      This should work, but it doesn't
7008   sctx->ctx = ctx;
7009   mexMakeArrayPersistent(sctx->ctx);
7010   */
7011   sctx->ctx = mxDuplicateArray(ctx);
7012 
7013   ierr = TSSetIJacobian(ts,A,B,TSComputeJacobian_Matlab,sctx);CHKERRQ(ierr);
7014   PetscFunctionReturn(0);
7015 }
7016 
7017 /*
7018    TSMonitor_Matlab - Calls the function that has been set with TSMonitorSetMatlab().
7019 
7020    Collective on TS
7021 
7022 .seealso: TSSetFunction(), TSGetFunction()
7023 @*/
7024 PetscErrorCode  TSMonitor_Matlab(TS ts,PetscInt it, PetscReal time,Vec u, void *ctx)
7025 {
7026   PetscErrorCode  ierr;
7027   TSMatlabContext *sctx = (TSMatlabContext*)ctx;
7028   int             nlhs  = 1,nrhs = 6;
7029   mxArray         *plhs[1],*prhs[6];
7030   long long int   lx = 0,ls = 0;
7031 
7032   PetscFunctionBegin;
7033   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
7034   PetscValidHeaderSpecific(u,VEC_CLASSID,4);
7035 
7036   ierr = PetscMemcpy(&ls,&ts,sizeof(ts));CHKERRQ(ierr);
7037   ierr = PetscMemcpy(&lx,&u,sizeof(u));CHKERRQ(ierr);
7038 
7039   prhs[0] =  mxCreateDoubleScalar((double)ls);
7040   prhs[1] =  mxCreateDoubleScalar((double)it);
7041   prhs[2] =  mxCreateDoubleScalar((double)time);
7042   prhs[3] =  mxCreateDoubleScalar((double)lx);
7043   prhs[4] =  mxCreateString(sctx->funcname);
7044   prhs[5] =  sctx->ctx;
7045   ierr    =  mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscTSMonitorInternal");CHKERRQ(ierr);
7046   ierr    =  mxGetScalar(plhs[0]);CHKERRQ(ierr);
7047   mxDestroyArray(prhs[0]);
7048   mxDestroyArray(prhs[1]);
7049   mxDestroyArray(prhs[2]);
7050   mxDestroyArray(prhs[3]);
7051   mxDestroyArray(prhs[4]);
7052   mxDestroyArray(plhs[0]);
7053   PetscFunctionReturn(0);
7054 }
7055 
7056 /*
7057    TSMonitorSetMatlab - Sets the monitor function from Matlab
7058 
7059    Level: developer
7060 
7061 .keywords: TS, nonlinear, set, function
7062 
7063 .seealso: TSGetFunction(), TSComputeFunction(), TSSetJacobian(), TSSetFunction()
7064 */
7065 PetscErrorCode  TSMonitorSetMatlab(TS ts,const char *func,mxArray *ctx)
7066 {
7067   PetscErrorCode  ierr;
7068   TSMatlabContext *sctx;
7069 
7070   PetscFunctionBegin;
7071   /* currently sctx is memory bleed */
7072   ierr = PetscNew(&sctx);CHKERRQ(ierr);
7073   ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr);
7074   /*
7075      This should work, but it doesn't
7076   sctx->ctx = ctx;
7077   mexMakeArrayPersistent(sctx->ctx);
7078   */
7079   sctx->ctx = mxDuplicateArray(ctx);
7080 
7081   ierr = TSMonitorSet(ts,TSMonitor_Matlab,sctx,NULL);CHKERRQ(ierr);
7082   PetscFunctionReturn(0);
7083 }
7084 #endif
7085 
7086 /*@C
7087    TSMonitorLGSolution - Monitors progress of the TS solvers by plotting each component of the solution vector
7088        in a time based line graph
7089 
7090    Collective on TS
7091 
7092    Input Parameters:
7093 +  ts - the TS context
7094 .  step - current time-step
7095 .  ptime - current time
7096 .  u - current solution
7097 -  dctx - the TSMonitorLGCtx object that contains all the options for the monitoring, this is created with TSMonitorLGCtxCreate()
7098 
7099    Options Database:
7100 .   -ts_monitor_lg_solution_variables
7101 
7102    Level: intermediate
7103 
7104    Notes: Each process in a parallel run displays its component solutions in a separate window
7105 
7106 .keywords: TS,  vector, monitor, view
7107 
7108 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorLGCtxCreate(), TSMonitorLGCtxSetVariableNames(), TSMonitorLGCtxGetVariableNames(),
7109            TSMonitorLGSetVariableNames(), TSMonitorLGGetVariableNames(), TSMonitorLGSetDisplayVariables(), TSMonitorLGCtxSetDisplayVariables(),
7110            TSMonitorLGCtxSetTransform(), TSMonitorLGSetTransform(), TSMonitorLGError(), TSMonitorLGSNESIterations(), TSMonitorLGKSPIterations(),
7111            TSMonitorEnvelopeCtxCreate(), TSMonitorEnvelopeGetBounds(), TSMonitorEnvelopeCtxDestroy(), TSMonitorEnvelop()
7112 @*/
7113 PetscErrorCode  TSMonitorLGSolution(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dctx)
7114 {
7115   PetscErrorCode    ierr;
7116   TSMonitorLGCtx    ctx = (TSMonitorLGCtx)dctx;
7117   const PetscScalar *yy;
7118   Vec               v;
7119 
7120   PetscFunctionBegin;
7121   if (step < 0) PetscFunctionReturn(0); /* -1 indicates interpolated solution */
7122   if (!step) {
7123     PetscDrawAxis axis;
7124     PetscInt      dim;
7125     ierr = PetscDrawLGGetAxis(ctx->lg,&axis);CHKERRQ(ierr);
7126     ierr = PetscDrawAxisSetLabels(axis,"Solution as function of time","Time","Solution");CHKERRQ(ierr);
7127     if (!ctx->names) {
7128       PetscBool flg;
7129       /* user provides names of variables to plot but no names has been set so assume names are integer values */
7130       ierr = PetscOptionsHasName(((PetscObject)ts)->options,((PetscObject)ts)->prefix,"-ts_monitor_lg_solution_variables",&flg);CHKERRQ(ierr);
7131       if (flg) {
7132         PetscInt i,n;
7133         char     **names;
7134         ierr = VecGetSize(u,&n);CHKERRQ(ierr);
7135         ierr = PetscMalloc1(n+1,&names);CHKERRQ(ierr);
7136         for (i=0; i<n; i++) {
7137           ierr = PetscMalloc1(5,&names[i]);CHKERRQ(ierr);
7138           ierr = PetscSNPrintf(names[i],5,"%D",i);CHKERRQ(ierr);
7139         }
7140         names[n] = NULL;
7141         ctx->names = names;
7142       }
7143     }
7144     if (ctx->names && !ctx->displaynames) {
7145       char      **displaynames;
7146       PetscBool flg;
7147       ierr = VecGetLocalSize(u,&dim);CHKERRQ(ierr);
7148       ierr = PetscMalloc1(dim+1,&displaynames);CHKERRQ(ierr);
7149       ierr = PetscMemzero(displaynames,(dim+1)*sizeof(char*));CHKERRQ(ierr);
7150       ierr = PetscOptionsGetStringArray(((PetscObject)ts)->options,((PetscObject)ts)->prefix,"-ts_monitor_lg_solution_variables",displaynames,&dim,&flg);CHKERRQ(ierr);
7151       if (flg) {
7152         ierr = TSMonitorLGCtxSetDisplayVariables(ctx,(const char *const *)displaynames);CHKERRQ(ierr);
7153       }
7154       ierr = PetscStrArrayDestroy(&displaynames);CHKERRQ(ierr);
7155     }
7156     if (ctx->displaynames) {
7157       ierr = PetscDrawLGSetDimension(ctx->lg,ctx->ndisplayvariables);CHKERRQ(ierr);
7158       ierr = PetscDrawLGSetLegend(ctx->lg,(const char *const *)ctx->displaynames);CHKERRQ(ierr);
7159     } else if (ctx->names) {
7160       ierr = VecGetLocalSize(u,&dim);CHKERRQ(ierr);
7161       ierr = PetscDrawLGSetDimension(ctx->lg,dim);CHKERRQ(ierr);
7162       ierr = PetscDrawLGSetLegend(ctx->lg,(const char *const *)ctx->names);CHKERRQ(ierr);
7163     } else {
7164       ierr = VecGetLocalSize(u,&dim);CHKERRQ(ierr);
7165       ierr = PetscDrawLGSetDimension(ctx->lg,dim);CHKERRQ(ierr);
7166     }
7167     ierr = PetscDrawLGReset(ctx->lg);CHKERRQ(ierr);
7168   }
7169 
7170   if (!ctx->transform) v = u;
7171   else {ierr = (*ctx->transform)(ctx->transformctx,u,&v);CHKERRQ(ierr);}
7172   ierr = VecGetArrayRead(v,&yy);CHKERRQ(ierr);
7173   if (ctx->displaynames) {
7174     PetscInt i;
7175     for (i=0; i<ctx->ndisplayvariables; i++)
7176       ctx->displayvalues[i] = PetscRealPart(yy[ctx->displayvariables[i]]);
7177     ierr = PetscDrawLGAddCommonPoint(ctx->lg,ptime,ctx->displayvalues);CHKERRQ(ierr);
7178   } else {
7179 #if defined(PETSC_USE_COMPLEX)
7180     PetscInt  i,n;
7181     PetscReal *yreal;
7182     ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr);
7183     ierr = PetscMalloc1(n,&yreal);CHKERRQ(ierr);
7184     for (i=0; i<n; i++) yreal[i] = PetscRealPart(yy[i]);
7185     ierr = PetscDrawLGAddCommonPoint(ctx->lg,ptime,yreal);CHKERRQ(ierr);
7186     ierr = PetscFree(yreal);CHKERRQ(ierr);
7187 #else
7188     ierr = PetscDrawLGAddCommonPoint(ctx->lg,ptime,yy);CHKERRQ(ierr);
7189 #endif
7190   }
7191   ierr = VecRestoreArrayRead(v,&yy);CHKERRQ(ierr);
7192   if (ctx->transform) {ierr = VecDestroy(&v);CHKERRQ(ierr);}
7193 
7194   if (((ctx->howoften > 0) && (!(step % ctx->howoften))) || ((ctx->howoften == -1) && ts->reason)) {
7195     ierr = PetscDrawLGDraw(ctx->lg);CHKERRQ(ierr);
7196     ierr = PetscDrawLGSave(ctx->lg);CHKERRQ(ierr);
7197   }
7198   PetscFunctionReturn(0);
7199 }
7200 
7201 /*@C
7202    TSMonitorLGSetVariableNames - Sets the name of each component in the solution vector so that it may be displayed in the plot
7203 
7204    Collective on TS
7205 
7206    Input Parameters:
7207 +  ts - the TS context
7208 -  names - the names of the components, final string must be NULL
7209 
7210    Level: intermediate
7211 
7212    Notes: If the TS object does not have a TSMonitorLGCtx associated with it then this function is ignored
7213 
7214 .keywords: TS,  vector, monitor, view
7215 
7216 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorLGSetDisplayVariables(), TSMonitorLGCtxSetVariableNames()
7217 @*/
7218 PetscErrorCode  TSMonitorLGSetVariableNames(TS ts,const char * const *names)
7219 {
7220   PetscErrorCode    ierr;
7221   PetscInt          i;
7222 
7223   PetscFunctionBegin;
7224   for (i=0; i<ts->numbermonitors; i++) {
7225     if (ts->monitor[i] == TSMonitorLGSolution) {
7226       ierr = TSMonitorLGCtxSetVariableNames((TSMonitorLGCtx)ts->monitorcontext[i],names);CHKERRQ(ierr);
7227       break;
7228     }
7229   }
7230   PetscFunctionReturn(0);
7231 }
7232 
7233 /*@C
7234    TSMonitorLGCtxSetVariableNames - Sets the name of each component in the solution vector so that it may be displayed in the plot
7235 
7236    Collective on TS
7237 
7238    Input Parameters:
7239 +  ts - the TS context
7240 -  names - the names of the components, final string must be NULL
7241 
7242    Level: intermediate
7243 
7244 .keywords: TS,  vector, monitor, view
7245 
7246 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorLGSetDisplayVariables(), TSMonitorLGSetVariableNames()
7247 @*/
7248 PetscErrorCode  TSMonitorLGCtxSetVariableNames(TSMonitorLGCtx ctx,const char * const *names)
7249 {
7250   PetscErrorCode    ierr;
7251 
7252   PetscFunctionBegin;
7253   ierr = PetscStrArrayDestroy(&ctx->names);CHKERRQ(ierr);
7254   ierr = PetscStrArrayallocpy(names,&ctx->names);CHKERRQ(ierr);
7255   PetscFunctionReturn(0);
7256 }
7257 
7258 /*@C
7259    TSMonitorLGGetVariableNames - Gets the name of each component in the solution vector so that it may be displayed in the plot
7260 
7261    Collective on TS
7262 
7263    Input Parameter:
7264 .  ts - the TS context
7265 
7266    Output Parameter:
7267 .  names - the names of the components, final string must be NULL
7268 
7269    Level: intermediate
7270 
7271    Notes: If the TS object does not have a TSMonitorLGCtx associated with it then this function is ignored
7272 
7273 .keywords: TS,  vector, monitor, view
7274 
7275 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorLGSetDisplayVariables()
7276 @*/
7277 PetscErrorCode  TSMonitorLGGetVariableNames(TS ts,const char *const **names)
7278 {
7279   PetscInt       i;
7280 
7281   PetscFunctionBegin;
7282   *names = NULL;
7283   for (i=0; i<ts->numbermonitors; i++) {
7284     if (ts->monitor[i] == TSMonitorLGSolution) {
7285       TSMonitorLGCtx  ctx = (TSMonitorLGCtx) ts->monitorcontext[i];
7286       *names = (const char *const *)ctx->names;
7287       break;
7288     }
7289   }
7290   PetscFunctionReturn(0);
7291 }
7292 
7293 /*@C
7294    TSMonitorLGCtxSetDisplayVariables - Sets the variables that are to be display in the monitor
7295 
7296    Collective on TS
7297 
7298    Input Parameters:
7299 +  ctx - the TSMonitorLG context
7300 .  displaynames - the names of the components, final string must be NULL
7301 
7302    Level: intermediate
7303 
7304 .keywords: TS,  vector, monitor, view
7305 
7306 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorLGSetVariableNames()
7307 @*/
7308 PetscErrorCode  TSMonitorLGCtxSetDisplayVariables(TSMonitorLGCtx ctx,const char * const *displaynames)
7309 {
7310   PetscInt          j = 0,k;
7311   PetscErrorCode    ierr;
7312 
7313   PetscFunctionBegin;
7314   if (!ctx->names) PetscFunctionReturn(0);
7315   ierr = PetscStrArrayDestroy(&ctx->displaynames);CHKERRQ(ierr);
7316   ierr = PetscStrArrayallocpy(displaynames,&ctx->displaynames);CHKERRQ(ierr);
7317   while (displaynames[j]) j++;
7318   ctx->ndisplayvariables = j;
7319   ierr = PetscMalloc1(ctx->ndisplayvariables,&ctx->displayvariables);CHKERRQ(ierr);
7320   ierr = PetscMalloc1(ctx->ndisplayvariables,&ctx->displayvalues);CHKERRQ(ierr);
7321   j = 0;
7322   while (displaynames[j]) {
7323     k = 0;
7324     while (ctx->names[k]) {
7325       PetscBool flg;
7326       ierr = PetscStrcmp(displaynames[j],ctx->names[k],&flg);CHKERRQ(ierr);
7327       if (flg) {
7328         ctx->displayvariables[j] = k;
7329         break;
7330       }
7331       k++;
7332     }
7333     j++;
7334   }
7335   PetscFunctionReturn(0);
7336 }
7337 
7338 /*@C
7339    TSMonitorLGSetDisplayVariables - Sets the variables that are to be display in the monitor
7340 
7341    Collective on TS
7342 
7343    Input Parameters:
7344 +  ts - the TS context
7345 .  displaynames - the names of the components, final string must be NULL
7346 
7347    Notes: If the TS object does not have a TSMonitorLGCtx associated with it then this function is ignored
7348 
7349    Level: intermediate
7350 
7351 .keywords: TS,  vector, monitor, view
7352 
7353 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorLGSetVariableNames()
7354 @*/
7355 PetscErrorCode  TSMonitorLGSetDisplayVariables(TS ts,const char * const *displaynames)
7356 {
7357   PetscInt          i;
7358   PetscErrorCode    ierr;
7359 
7360   PetscFunctionBegin;
7361   for (i=0; i<ts->numbermonitors; i++) {
7362     if (ts->monitor[i] == TSMonitorLGSolution) {
7363       ierr = TSMonitorLGCtxSetDisplayVariables((TSMonitorLGCtx)ts->monitorcontext[i],displaynames);CHKERRQ(ierr);
7364       break;
7365     }
7366   }
7367   PetscFunctionReturn(0);
7368 }
7369 
7370 /*@C
7371    TSMonitorLGSetTransform - Solution vector will be transformed by provided function before being displayed
7372 
7373    Collective on TS
7374 
7375    Input Parameters:
7376 +  ts - the TS context
7377 .  transform - the transform function
7378 .  destroy - function to destroy the optional context
7379 -  ctx - optional context used by transform function
7380 
7381    Notes: If the TS object does not have a TSMonitorLGCtx associated with it then this function is ignored
7382 
7383    Level: intermediate
7384 
7385 .keywords: TS,  vector, monitor, view
7386 
7387 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorLGSetVariableNames(), TSMonitorLGCtxSetTransform()
7388 @*/
7389 PetscErrorCode  TSMonitorLGSetTransform(TS ts,PetscErrorCode (*transform)(void*,Vec,Vec*),PetscErrorCode (*destroy)(void*),void *tctx)
7390 {
7391   PetscInt          i;
7392   PetscErrorCode    ierr;
7393 
7394   PetscFunctionBegin;
7395   for (i=0; i<ts->numbermonitors; i++) {
7396     if (ts->monitor[i] == TSMonitorLGSolution) {
7397       ierr = TSMonitorLGCtxSetTransform((TSMonitorLGCtx)ts->monitorcontext[i],transform,destroy,tctx);CHKERRQ(ierr);
7398     }
7399   }
7400   PetscFunctionReturn(0);
7401 }
7402 
7403 /*@C
7404    TSMonitorLGCtxSetTransform - Solution vector will be transformed by provided function before being displayed
7405 
7406    Collective on TSLGCtx
7407 
7408    Input Parameters:
7409 +  ts - the TS context
7410 .  transform - the transform function
7411 .  destroy - function to destroy the optional context
7412 -  ctx - optional context used by transform function
7413 
7414    Level: intermediate
7415 
7416 .keywords: TS,  vector, monitor, view
7417 
7418 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorLGSetVariableNames(), TSMonitorLGSetTransform()
7419 @*/
7420 PetscErrorCode  TSMonitorLGCtxSetTransform(TSMonitorLGCtx ctx,PetscErrorCode (*transform)(void*,Vec,Vec*),PetscErrorCode (*destroy)(void*),void *tctx)
7421 {
7422   PetscFunctionBegin;
7423   ctx->transform    = transform;
7424   ctx->transformdestroy = destroy;
7425   ctx->transformctx = tctx;
7426   PetscFunctionReturn(0);
7427 }
7428 
7429 /*@C
7430    TSMonitorLGError - Monitors progress of the TS solvers by plotting each component of the solution vector
7431        in a time based line graph
7432 
7433    Collective on TS
7434 
7435    Input Parameters:
7436 +  ts - the TS context
7437 .  step - current time-step
7438 .  ptime - current time
7439 .  u - current solution
7440 -  dctx - TSMonitorLGCtx object created with TSMonitorLGCtxCreate()
7441 
7442    Level: intermediate
7443 
7444    Notes: Each process in a parallel run displays its component errors in a separate window
7445 
7446    The user must provide the solution using TSSetSolutionFunction() to use this monitor.
7447 
7448    Options Database Keys:
7449 .  -ts_monitor_lg_error - create a graphical monitor of error history
7450 
7451 .keywords: TS,  vector, monitor, view
7452 
7453 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSSetSolutionFunction()
7454 @*/
7455 PetscErrorCode  TSMonitorLGError(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dummy)
7456 {
7457   PetscErrorCode    ierr;
7458   TSMonitorLGCtx    ctx = (TSMonitorLGCtx)dummy;
7459   const PetscScalar *yy;
7460   Vec               y;
7461 
7462   PetscFunctionBegin;
7463   if (!step) {
7464     PetscDrawAxis axis;
7465     PetscInt      dim;
7466     ierr = PetscDrawLGGetAxis(ctx->lg,&axis);CHKERRQ(ierr);
7467     ierr = PetscDrawAxisSetLabels(axis,"Error in solution as function of time","Time","Solution");CHKERRQ(ierr);
7468     ierr = VecGetLocalSize(u,&dim);CHKERRQ(ierr);
7469     ierr = PetscDrawLGSetDimension(ctx->lg,dim);CHKERRQ(ierr);
7470     ierr = PetscDrawLGReset(ctx->lg);CHKERRQ(ierr);
7471   }
7472   ierr = VecDuplicate(u,&y);CHKERRQ(ierr);
7473   ierr = TSComputeSolutionFunction(ts,ptime,y);CHKERRQ(ierr);
7474   ierr = VecAXPY(y,-1.0,u);CHKERRQ(ierr);
7475   ierr = VecGetArrayRead(y,&yy);CHKERRQ(ierr);
7476 #if defined(PETSC_USE_COMPLEX)
7477   {
7478     PetscReal *yreal;
7479     PetscInt  i,n;
7480     ierr = VecGetLocalSize(y,&n);CHKERRQ(ierr);
7481     ierr = PetscMalloc1(n,&yreal);CHKERRQ(ierr);
7482     for (i=0; i<n; i++) yreal[i] = PetscRealPart(yy[i]);
7483     ierr = PetscDrawLGAddCommonPoint(ctx->lg,ptime,yreal);CHKERRQ(ierr);
7484     ierr = PetscFree(yreal);CHKERRQ(ierr);
7485   }
7486 #else
7487   ierr = PetscDrawLGAddCommonPoint(ctx->lg,ptime,yy);CHKERRQ(ierr);
7488 #endif
7489   ierr = VecRestoreArrayRead(y,&yy);CHKERRQ(ierr);
7490   ierr = VecDestroy(&y);CHKERRQ(ierr);
7491   if (((ctx->howoften > 0) && (!(step % ctx->howoften))) || ((ctx->howoften == -1) && ts->reason)) {
7492     ierr = PetscDrawLGDraw(ctx->lg);CHKERRQ(ierr);
7493     ierr = PetscDrawLGSave(ctx->lg);CHKERRQ(ierr);
7494   }
7495   PetscFunctionReturn(0);
7496 }
7497 
7498 PetscErrorCode TSMonitorLGSNESIterations(TS ts,PetscInt n,PetscReal ptime,Vec v,void *monctx)
7499 {
7500   TSMonitorLGCtx ctx = (TSMonitorLGCtx) monctx;
7501   PetscReal      x   = ptime,y;
7502   PetscErrorCode ierr;
7503   PetscInt       its;
7504 
7505   PetscFunctionBegin;
7506   if (n < 0) PetscFunctionReturn(0); /* -1 indicates interpolated solution */
7507   if (!n) {
7508     PetscDrawAxis axis;
7509     ierr = PetscDrawLGGetAxis(ctx->lg,&axis);CHKERRQ(ierr);
7510     ierr = PetscDrawAxisSetLabels(axis,"Nonlinear iterations as function of time","Time","SNES Iterations");CHKERRQ(ierr);
7511     ierr = PetscDrawLGReset(ctx->lg);CHKERRQ(ierr);
7512     ctx->snes_its = 0;
7513   }
7514   ierr = TSGetSNESIterations(ts,&its);CHKERRQ(ierr);
7515   y    = its - ctx->snes_its;
7516   ierr = PetscDrawLGAddPoint(ctx->lg,&x,&y);CHKERRQ(ierr);
7517   if (((ctx->howoften > 0) && (!(n % ctx->howoften)) && (n > -1)) || ((ctx->howoften == -1) && (n == -1))) {
7518     ierr = PetscDrawLGDraw(ctx->lg);CHKERRQ(ierr);
7519     ierr = PetscDrawLGSave(ctx->lg);CHKERRQ(ierr);
7520   }
7521   ctx->snes_its = its;
7522   PetscFunctionReturn(0);
7523 }
7524 
7525 PetscErrorCode TSMonitorLGKSPIterations(TS ts,PetscInt n,PetscReal ptime,Vec v,void *monctx)
7526 {
7527   TSMonitorLGCtx ctx = (TSMonitorLGCtx) monctx;
7528   PetscReal      x   = ptime,y;
7529   PetscErrorCode ierr;
7530   PetscInt       its;
7531 
7532   PetscFunctionBegin;
7533   if (n < 0) PetscFunctionReturn(0); /* -1 indicates interpolated solution */
7534   if (!n) {
7535     PetscDrawAxis axis;
7536     ierr = PetscDrawLGGetAxis(ctx->lg,&axis);CHKERRQ(ierr);
7537     ierr = PetscDrawAxisSetLabels(axis,"Linear iterations as function of time","Time","KSP Iterations");CHKERRQ(ierr);
7538     ierr = PetscDrawLGReset(ctx->lg);CHKERRQ(ierr);
7539     ctx->ksp_its = 0;
7540   }
7541   ierr = TSGetKSPIterations(ts,&its);CHKERRQ(ierr);
7542   y    = its - ctx->ksp_its;
7543   ierr = PetscDrawLGAddPoint(ctx->lg,&x,&y);CHKERRQ(ierr);
7544   if (((ctx->howoften > 0) && (!(n % ctx->howoften)) && (n > -1)) || ((ctx->howoften == -1) && (n == -1))) {
7545     ierr = PetscDrawLGDraw(ctx->lg);CHKERRQ(ierr);
7546     ierr = PetscDrawLGSave(ctx->lg);CHKERRQ(ierr);
7547   }
7548   ctx->ksp_its = its;
7549   PetscFunctionReturn(0);
7550 }
7551 
7552 /*@
7553    TSComputeLinearStability - computes the linear stability function at a point
7554 
7555    Collective on TS and Vec
7556 
7557    Input Parameters:
7558 +  ts - the TS context
7559 -  xr,xi - real and imaginary part of input arguments
7560 
7561    Output Parameters:
7562 .  yr,yi - real and imaginary part of function value
7563 
7564    Level: developer
7565 
7566 .keywords: TS, compute
7567 
7568 .seealso: TSSetRHSFunction(), TSComputeIFunction()
7569 @*/
7570 PetscErrorCode TSComputeLinearStability(TS ts,PetscReal xr,PetscReal xi,PetscReal *yr,PetscReal *yi)
7571 {
7572   PetscErrorCode ierr;
7573 
7574   PetscFunctionBegin;
7575   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
7576   if (!ts->ops->linearstability) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"Linearized stability function not provided for this method");
7577   ierr = (*ts->ops->linearstability)(ts,xr,xi,yr,yi);CHKERRQ(ierr);
7578   PetscFunctionReturn(0);
7579 }
7580 
7581 /* ------------------------------------------------------------------------*/
7582 /*@C
7583    TSMonitorEnvelopeCtxCreate - Creates a context for use with TSMonitorEnvelope()
7584 
7585    Collective on TS
7586 
7587    Input Parameters:
7588 .  ts  - the ODE solver object
7589 
7590    Output Parameter:
7591 .  ctx - the context
7592 
7593    Level: intermediate
7594 
7595 .keywords: TS, monitor, line graph, residual, seealso
7596 
7597 .seealso: TSMonitorLGTimeStep(), TSMonitorSet(), TSMonitorLGSolution(), TSMonitorLGError()
7598 
7599 @*/
7600 PetscErrorCode  TSMonitorEnvelopeCtxCreate(TS ts,TSMonitorEnvelopeCtx *ctx)
7601 {
7602   PetscErrorCode ierr;
7603 
7604   PetscFunctionBegin;
7605   ierr = PetscNew(ctx);CHKERRQ(ierr);
7606   PetscFunctionReturn(0);
7607 }
7608 
7609 /*@C
7610    TSMonitorEnvelope - Monitors the maximum and minimum value of each component of the solution
7611 
7612    Collective on TS
7613 
7614    Input Parameters:
7615 +  ts - the TS context
7616 .  step - current time-step
7617 .  ptime - current time
7618 .  u  - current solution
7619 -  dctx - the envelope context
7620 
7621    Options Database:
7622 .  -ts_monitor_envelope
7623 
7624    Level: intermediate
7625 
7626    Notes: after a solve you can use TSMonitorEnvelopeGetBounds() to access the envelope
7627 
7628 .keywords: TS,  vector, monitor, view
7629 
7630 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorEnvelopeGetBounds(), TSMonitorEnvelopeCtxCreate()
7631 @*/
7632 PetscErrorCode  TSMonitorEnvelope(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dctx)
7633 {
7634   PetscErrorCode       ierr;
7635   TSMonitorEnvelopeCtx ctx = (TSMonitorEnvelopeCtx)dctx;
7636 
7637   PetscFunctionBegin;
7638   if (!ctx->max) {
7639     ierr = VecDuplicate(u,&ctx->max);CHKERRQ(ierr);
7640     ierr = VecDuplicate(u,&ctx->min);CHKERRQ(ierr);
7641     ierr = VecCopy(u,ctx->max);CHKERRQ(ierr);
7642     ierr = VecCopy(u,ctx->min);CHKERRQ(ierr);
7643   } else {
7644     ierr = VecPointwiseMax(ctx->max,u,ctx->max);CHKERRQ(ierr);
7645     ierr = VecPointwiseMin(ctx->min,u,ctx->min);CHKERRQ(ierr);
7646   }
7647   PetscFunctionReturn(0);
7648 }
7649 
7650 /*@C
7651    TSMonitorEnvelopeGetBounds - Gets the bounds for the components of the solution
7652 
7653    Collective on TS
7654 
7655    Input Parameter:
7656 .  ts - the TS context
7657 
7658    Output Parameter:
7659 +  max - the maximum values
7660 -  min - the minimum values
7661 
7662    Notes: If the TS does not have a TSMonitorEnvelopeCtx associated with it then this function is ignored
7663 
7664    Level: intermediate
7665 
7666 .keywords: TS,  vector, monitor, view
7667 
7668 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorLGSetDisplayVariables()
7669 @*/
7670 PetscErrorCode  TSMonitorEnvelopeGetBounds(TS ts,Vec *max,Vec *min)
7671 {
7672   PetscInt i;
7673 
7674   PetscFunctionBegin;
7675   if (max) *max = NULL;
7676   if (min) *min = NULL;
7677   for (i=0; i<ts->numbermonitors; i++) {
7678     if (ts->monitor[i] == TSMonitorEnvelope) {
7679       TSMonitorEnvelopeCtx  ctx = (TSMonitorEnvelopeCtx) ts->monitorcontext[i];
7680       if (max) *max = ctx->max;
7681       if (min) *min = ctx->min;
7682       break;
7683     }
7684   }
7685   PetscFunctionReturn(0);
7686 }
7687 
7688 /*@C
7689    TSMonitorEnvelopeCtxDestroy - Destroys a context that was created  with TSMonitorEnvelopeCtxCreate().
7690 
7691    Collective on TSMonitorEnvelopeCtx
7692 
7693    Input Parameter:
7694 .  ctx - the monitor context
7695 
7696    Level: intermediate
7697 
7698 .keywords: TS, monitor, line graph, destroy
7699 
7700 .seealso: TSMonitorLGCtxCreate(),  TSMonitorSet(), TSMonitorLGTimeStep()
7701 @*/
7702 PetscErrorCode  TSMonitorEnvelopeCtxDestroy(TSMonitorEnvelopeCtx *ctx)
7703 {
7704   PetscErrorCode ierr;
7705 
7706   PetscFunctionBegin;
7707   ierr = VecDestroy(&(*ctx)->min);CHKERRQ(ierr);
7708   ierr = VecDestroy(&(*ctx)->max);CHKERRQ(ierr);
7709   ierr = PetscFree(*ctx);CHKERRQ(ierr);
7710   PetscFunctionReturn(0);
7711 }
7712 
7713 /*@
7714    TSRollBack - Rolls back one time step
7715 
7716    Collective on TS
7717 
7718    Input Parameter:
7719 .  ts - the TS context obtained from TSCreate()
7720 
7721    Level: advanced
7722 
7723 .keywords: TS, timestep, rollback
7724 
7725 .seealso: TSCreate(), TSSetUp(), TSDestroy(), TSSolve(), TSSetPreStep(), TSSetPreStage(), TSInterpolate()
7726 @*/
7727 PetscErrorCode  TSRollBack(TS ts)
7728 {
7729   PetscErrorCode ierr;
7730 
7731   PetscFunctionBegin;
7732   PetscValidHeaderSpecific(ts, TS_CLASSID,1);
7733   if (ts->steprollback) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_ARG_WRONGSTATE,"TSRollBack already called");
7734   if (!ts->ops->rollback) SETERRQ1(PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"TSRollBack not implemented for type '%s'",((PetscObject)ts)->type_name);
7735   ierr = (*ts->ops->rollback)(ts);CHKERRQ(ierr);
7736   ts->time_step = ts->ptime - ts->ptime_prev;
7737   ts->ptime = ts->ptime_prev;
7738   ts->ptime_prev = ts->ptime_prev_rollback;
7739   ts->steps--;
7740   ierr = TSPostEvaluate(ts);CHKERRQ(ierr);
7741   ts->steprollback = PETSC_TRUE;
7742   PetscFunctionReturn(0);
7743 }
7744 
7745 /*@
7746    TSGetStages - Get the number of stages and stage values
7747 
7748    Input Parameter:
7749 .  ts - the TS context obtained from TSCreate()
7750 
7751    Level: advanced
7752 
7753 .keywords: TS, getstages
7754 
7755 .seealso: TSCreate()
7756 @*/
7757 PetscErrorCode  TSGetStages(TS ts,PetscInt *ns,Vec **Y)
7758 {
7759   PetscErrorCode ierr;
7760 
7761   PetscFunctionBegin;
7762   PetscValidHeaderSpecific(ts, TS_CLASSID,1);
7763   PetscValidPointer(ns,2);
7764 
7765   if (!ts->ops->getstages) *ns=0;
7766   else {
7767     ierr = (*ts->ops->getstages)(ts,ns,Y);CHKERRQ(ierr);
7768   }
7769   PetscFunctionReturn(0);
7770 }
7771 
7772 /*@C
7773   TSComputeIJacobianDefaultColor - Computes the Jacobian using finite differences and coloring to exploit matrix sparsity.
7774 
7775   Collective on SNES
7776 
7777   Input Parameters:
7778 + ts - the TS context
7779 . t - current timestep
7780 . U - state vector
7781 . Udot - time derivative of state vector
7782 . shift - shift to apply, see note below
7783 - ctx - an optional user context
7784 
7785   Output Parameters:
7786 + J - Jacobian matrix (not altered in this routine)
7787 - B - newly computed Jacobian matrix to use with preconditioner (generally the same as J)
7788 
7789   Level: intermediate
7790 
7791   Notes:
7792   If F(t,U,Udot)=0 is the DAE, the required Jacobian is
7793 
7794   dF/dU + shift*dF/dUdot
7795 
7796   Most users should not need to explicitly call this routine, as it
7797   is used internally within the nonlinear solvers.
7798 
7799   This will first try to get the coloring from the DM.  If the DM type has no coloring
7800   routine, then it will try to get the coloring from the matrix.  This requires that the
7801   matrix have nonzero entries precomputed.
7802 
7803 .keywords: TS, finite differences, Jacobian, coloring, sparse
7804 .seealso: TSSetIJacobian(), MatFDColoringCreate(), MatFDColoringSetFunction()
7805 @*/
7806 PetscErrorCode TSComputeIJacobianDefaultColor(TS ts,PetscReal t,Vec U,Vec Udot,PetscReal shift,Mat J,Mat B,void *ctx)
7807 {
7808   SNES           snes;
7809   MatFDColoring  color;
7810   PetscBool      hascolor, matcolor = PETSC_FALSE;
7811   PetscErrorCode ierr;
7812 
7813   PetscFunctionBegin;
7814   ierr = PetscOptionsGetBool(((PetscObject)ts)->options,((PetscObject) ts)->prefix, "-ts_fd_color_use_mat", &matcolor, NULL);CHKERRQ(ierr);
7815   ierr = PetscObjectQuery((PetscObject) B, "TSMatFDColoring", (PetscObject *) &color);CHKERRQ(ierr);
7816   if (!color) {
7817     DM         dm;
7818     ISColoring iscoloring;
7819 
7820     ierr = TSGetDM(ts, &dm);CHKERRQ(ierr);
7821     ierr = DMHasColoring(dm, &hascolor);CHKERRQ(ierr);
7822     if (hascolor && !matcolor) {
7823       ierr = DMCreateColoring(dm, IS_COLORING_GLOBAL, &iscoloring);CHKERRQ(ierr);
7824       ierr = MatFDColoringCreate(B, iscoloring, &color);CHKERRQ(ierr);
7825       ierr = MatFDColoringSetFunction(color, (PetscErrorCode (*)(void)) SNESTSFormFunction, (void *) ts);CHKERRQ(ierr);
7826       ierr = MatFDColoringSetFromOptions(color);CHKERRQ(ierr);
7827       ierr = MatFDColoringSetUp(B, iscoloring, color);CHKERRQ(ierr);
7828       ierr = ISColoringDestroy(&iscoloring);CHKERRQ(ierr);
7829     } else {
7830       MatColoring mc;
7831 
7832       ierr = MatColoringCreate(B, &mc);CHKERRQ(ierr);
7833       ierr = MatColoringSetDistance(mc, 2);CHKERRQ(ierr);
7834       ierr = MatColoringSetType(mc, MATCOLORINGSL);CHKERRQ(ierr);
7835       ierr = MatColoringSetFromOptions(mc);CHKERRQ(ierr);
7836       ierr = MatColoringApply(mc, &iscoloring);CHKERRQ(ierr);
7837       ierr = MatColoringDestroy(&mc);CHKERRQ(ierr);
7838       ierr = MatFDColoringCreate(B, iscoloring, &color);CHKERRQ(ierr);
7839       ierr = MatFDColoringSetFunction(color, (PetscErrorCode (*)(void)) SNESTSFormFunction, (void *) ts);CHKERRQ(ierr);
7840       ierr = MatFDColoringSetFromOptions(color);CHKERRQ(ierr);
7841       ierr = MatFDColoringSetUp(B, iscoloring, color);CHKERRQ(ierr);
7842       ierr = ISColoringDestroy(&iscoloring);CHKERRQ(ierr);
7843     }
7844     ierr = PetscObjectCompose((PetscObject) B, "TSMatFDColoring", (PetscObject) color);CHKERRQ(ierr);
7845     ierr = PetscObjectDereference((PetscObject) color);CHKERRQ(ierr);
7846   }
7847   ierr = TSGetSNES(ts, &snes);CHKERRQ(ierr);
7848   ierr = MatFDColoringApply(B, color, U, snes);CHKERRQ(ierr);
7849   if (J != B) {
7850     ierr = MatAssemblyBegin(J, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
7851     ierr = MatAssemblyEnd(J, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
7852   }
7853   PetscFunctionReturn(0);
7854 }
7855 
7856 /*@
7857     TSSetFunctionDomainError - Set the function testing if the current state vector is valid
7858 
7859     Input Parameters:
7860     ts - the TS context
7861     func - function called within TSFunctionDomainError
7862 
7863     Level: intermediate
7864 
7865 .keywords: TS, state, domain
7866 .seealso: TSAdaptCheckStage(), TSFunctionDomainError()
7867 @*/
7868 
7869 PetscErrorCode TSSetFunctionDomainError(TS ts, PetscErrorCode (*func)(TS,PetscReal,Vec,PetscBool*))
7870 {
7871   PetscFunctionBegin;
7872   PetscValidHeaderSpecific(ts, TS_CLASSID,1);
7873   ts->functiondomainerror = func;
7874   PetscFunctionReturn(0);
7875 }
7876 
7877 /*@
7878     TSFunctionDomainError - Check if the current state is valid
7879 
7880     Input Parameters:
7881     ts - the TS context
7882     stagetime - time of the simulation
7883     Y - state vector to check.
7884 
7885     Output Parameter:
7886     accept - Set to PETSC_FALSE if the current state vector is valid.
7887 
7888     Note:
7889     This function should be used to ensure the state is in a valid part of the space.
7890     For example, one can ensure here all values are positive.
7891 
7892     Level: advanced
7893 @*/
7894 PetscErrorCode TSFunctionDomainError(TS ts,PetscReal stagetime,Vec Y,PetscBool* accept)
7895 {
7896   PetscErrorCode ierr;
7897 
7898   PetscFunctionBegin;
7899 
7900   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
7901   *accept = PETSC_TRUE;
7902   if (ts->functiondomainerror) {
7903     PetscStackCallStandard((*ts->functiondomainerror),(ts,stagetime,Y,accept));
7904   }
7905   PetscFunctionReturn(0);
7906 }
7907 
7908 /*@C
7909   TSClone - This function clones a time step object.
7910 
7911   Collective on MPI_Comm
7912 
7913   Input Parameter:
7914 . tsin    - The input TS
7915 
7916   Output Parameter:
7917 . tsout   - The output TS (cloned)
7918 
7919   Notes:
7920   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.
7921 
7922   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);
7923 
7924   Level: developer
7925 
7926 .keywords: TS, clone
7927 .seealso: TSCreate(), TSSetType(), TSSetUp(), TSDestroy(), TSSetProblemType()
7928 @*/
7929 PetscErrorCode  TSClone(TS tsin, TS *tsout)
7930 {
7931   TS             t;
7932   PetscErrorCode ierr;
7933   SNES           snes_start;
7934   DM             dm;
7935   TSType         type;
7936 
7937   PetscFunctionBegin;
7938   PetscValidPointer(tsin,1);
7939   *tsout = NULL;
7940 
7941   ierr = PetscHeaderCreate(t, TS_CLASSID, "TS", "Time stepping", "TS", PetscObjectComm((PetscObject)tsin), TSDestroy, TSView);CHKERRQ(ierr);
7942 
7943   /* General TS description */
7944   t->numbermonitors    = 0;
7945   t->setupcalled       = 0;
7946   t->ksp_its           = 0;
7947   t->snes_its          = 0;
7948   t->nwork             = 0;
7949   t->rhsjacobian.time  = -1e20;
7950   t->rhsjacobian.scale = 1.;
7951   t->ijacobian.shift   = 1.;
7952 
7953   ierr = TSGetSNES(tsin,&snes_start);CHKERRQ(ierr);
7954   ierr = TSSetSNES(t,snes_start);CHKERRQ(ierr);
7955 
7956   ierr = TSGetDM(tsin,&dm);CHKERRQ(ierr);
7957   ierr = TSSetDM(t,dm);CHKERRQ(ierr);
7958 
7959   t->adapt = tsin->adapt;
7960   ierr = PetscObjectReference((PetscObject)t->adapt);CHKERRQ(ierr);
7961 
7962   t->trajectory = tsin->trajectory;
7963   ierr = PetscObjectReference((PetscObject)t->trajectory);CHKERRQ(ierr);
7964 
7965   t->event = tsin->event;
7966   if (t->event) t->event->refct++;
7967 
7968   t->problem_type      = tsin->problem_type;
7969   t->ptime             = tsin->ptime;
7970   t->ptime_prev        = tsin->ptime_prev;
7971   t->time_step         = tsin->time_step;
7972   t->max_time          = tsin->max_time;
7973   t->steps             = tsin->steps;
7974   t->max_steps         = tsin->max_steps;
7975   t->equation_type     = tsin->equation_type;
7976   t->atol              = tsin->atol;
7977   t->rtol              = tsin->rtol;
7978   t->max_snes_failures = tsin->max_snes_failures;
7979   t->max_reject        = tsin->max_reject;
7980   t->errorifstepfailed = tsin->errorifstepfailed;
7981 
7982   ierr = TSGetType(tsin,&type);CHKERRQ(ierr);
7983   ierr = TSSetType(t,type);CHKERRQ(ierr);
7984 
7985   t->vec_sol           = NULL;
7986 
7987   t->cfltime          = tsin->cfltime;
7988   t->cfltime_local    = tsin->cfltime_local;
7989   t->exact_final_time = tsin->exact_final_time;
7990 
7991   ierr = PetscMemcpy(t->ops,tsin->ops,sizeof(struct _TSOps));CHKERRQ(ierr);
7992 
7993   if (((PetscObject)tsin)->fortran_func_pointers) {
7994     PetscInt i;
7995     ierr = PetscMalloc((10)*sizeof(void(*)(void)),&((PetscObject)t)->fortran_func_pointers);CHKERRQ(ierr);
7996     for (i=0; i<10; i++) {
7997       ((PetscObject)t)->fortran_func_pointers[i] = ((PetscObject)tsin)->fortran_func_pointers[i];
7998     }
7999   }
8000   *tsout = t;
8001   PetscFunctionReturn(0);
8002 }
8003