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