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