xref: /petsc/src/ts/interface/ts.c (revision 66320ccd443e79d0ca38afe8a1cc06b115cd0122)
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   ts->adjoint_max_steps = 0;
4494   PetscFunctionReturn(0);
4495 }
4496 
4497 /*@C
4498    TSMonitor - Runs all user-provided monitor routines set using TSMonitorSet()
4499 
4500    Collective on TS
4501 
4502    Input Parameters:
4503 +  ts - time stepping context obtained from TSCreate()
4504 .  step - step number that has just completed
4505 .  ptime - model time of the state
4506 -  u - state at the current model time
4507 
4508    Notes:
4509    TSMonitor() is typically used automatically within the time stepping implementations.
4510    Users would almost never call this routine directly.
4511 
4512    A step of -1 indicates that the monitor is being called on a solution obtained by interpolating from computed solutions
4513 
4514    Level: developer
4515 
4516 .keywords: TS, timestep
4517 @*/
4518 PetscErrorCode TSMonitor(TS ts,PetscInt step,PetscReal ptime,Vec u)
4519 {
4520   DM             dm;
4521   PetscInt       i,n = ts->numbermonitors;
4522   PetscErrorCode ierr;
4523 
4524   PetscFunctionBegin;
4525   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
4526   PetscValidHeaderSpecific(u,VEC_CLASSID,4);
4527 
4528   ierr = TSGetDM(ts,&dm);CHKERRQ(ierr);
4529   ierr = DMSetOutputSequenceNumber(dm,step,ptime);CHKERRQ(ierr);
4530 
4531   ierr = VecLockPush(u);CHKERRQ(ierr);
4532   for (i=0; i<n; i++) {
4533     ierr = (*ts->monitor[i])(ts,step,ptime,u,ts->monitorcontext[i]);CHKERRQ(ierr);
4534   }
4535   ierr = VecLockPop(u);CHKERRQ(ierr);
4536   PetscFunctionReturn(0);
4537 }
4538 
4539 /*@C
4540    TSAdjointMonitor - Runs all user-provided adjoint monitor routines set using TSAdjointMonitorSet()
4541 
4542    Collective on TS
4543 
4544    Input Parameters:
4545 +  ts - time stepping context obtained from TSCreate()
4546 .  step - step number that has just completed
4547 .  ptime - model time of the state
4548 .  u - state at the current model time
4549 .  numcost - number of cost functions (dimension of lambda  or mu)
4550 .  lambda - vectors containing the gradients of the cost functions with respect to the ODE/DAE solution variables
4551 -  mu - vectors containing the gradients of the cost functions with respect to the problem parameters
4552 
4553    Notes:
4554    TSAdjointMonitor() is typically used automatically within the time stepping implementations.
4555    Users would almost never call this routine directly.
4556 
4557    Level: developer
4558 
4559 .keywords: TS, timestep
4560 @*/
4561 PetscErrorCode TSAdjointMonitor(TS ts,PetscInt step,PetscReal ptime,Vec u,PetscInt numcost,Vec *lambda, Vec *mu)
4562 {
4563   PetscErrorCode ierr;
4564   PetscInt       i,n = ts->numberadjointmonitors;
4565 
4566   PetscFunctionBegin;
4567   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
4568   PetscValidHeaderSpecific(u,VEC_CLASSID,4);
4569   ierr = VecLockPush(u);CHKERRQ(ierr);
4570   for (i=0; i<n; i++) {
4571     ierr = (*ts->adjointmonitor[i])(ts,step,ptime,u,numcost,lambda,mu,ts->adjointmonitorcontext[i]);CHKERRQ(ierr);
4572   }
4573   ierr = VecLockPop(u);CHKERRQ(ierr);
4574   PetscFunctionReturn(0);
4575 }
4576 
4577 /* ------------------------------------------------------------------------*/
4578 /*@C
4579    TSMonitorLGCtxCreate - Creates a TSMonitorLGCtx context for use with
4580    TS to monitor the solution process graphically in various ways
4581 
4582    Collective on TS
4583 
4584    Input Parameters:
4585 +  host - the X display to open, or null for the local machine
4586 .  label - the title to put in the title bar
4587 .  x, y - the screen coordinates of the upper left coordinate of the window
4588 .  m, n - the screen width and height in pixels
4589 -  howoften - if positive then determines the frequency of the plotting, if -1 then only at the final time
4590 
4591    Output Parameter:
4592 .  ctx - the context
4593 
4594    Options Database Key:
4595 +  -ts_monitor_lg_timestep - automatically sets line graph monitor
4596 +  -ts_monitor_lg_timestep_log - automatically sets line graph monitor
4597 .  -ts_monitor_lg_solution - monitor the solution (or certain values of the solution by calling TSMonitorLGSetDisplayVariables() or TSMonitorLGCtxSetDisplayVariables())
4598 .  -ts_monitor_lg_error -  monitor the error
4599 .  -ts_monitor_lg_ksp_iterations - monitor the number of KSP iterations needed for each timestep
4600 .  -ts_monitor_lg_snes_iterations - monitor the number of SNES iterations needed for each timestep
4601 -  -lg_use_markers <true,false> - mark the data points (at each time step) on the plot; default is true
4602 
4603    Notes:
4604    Use TSMonitorLGCtxDestroy() to destroy.
4605 
4606    One can provide a function that transforms the solution before plotting it with TSMonitorLGCtxSetTransform() or TSMonitorLGSetTransform()
4607 
4608    Many of the functions that control the monitoring have two forms: TSMonitorLGSet/GetXXXX() and TSMonitorLGCtxSet/GetXXXX() the first take a TS object as the
4609    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
4610    as the first argument.
4611 
4612    One can control the names displayed for each solution or error variable with TSMonitorLGCtxSetVariableNames() or TSMonitorLGSetVariableNames()
4613 
4614    Level: intermediate
4615 
4616 .keywords: TS, monitor, line graph, residual
4617 
4618 .seealso: TSMonitorLGTimeStep(), TSMonitorSet(), TSMonitorLGSolution(), TSMonitorLGError(), TSMonitorDefault(), VecView(),
4619            TSMonitorLGCtxCreate(), TSMonitorLGCtxSetVariableNames(), TSMonitorLGCtxGetVariableNames(),
4620            TSMonitorLGSetVariableNames(), TSMonitorLGGetVariableNames(), TSMonitorLGSetDisplayVariables(), TSMonitorLGCtxSetDisplayVariables(),
4621            TSMonitorLGCtxSetTransform(), TSMonitorLGSetTransform(), TSMonitorLGError(), TSMonitorLGSNESIterations(), TSMonitorLGKSPIterations(),
4622            TSMonitorEnvelopeCtxCreate(), TSMonitorEnvelopeGetBounds(), TSMonitorEnvelopeCtxDestroy(), TSMonitorEnvelop()
4623 
4624 @*/
4625 PetscErrorCode  TSMonitorLGCtxCreate(MPI_Comm comm,const char host[],const char label[],int x,int y,int m,int n,PetscInt howoften,TSMonitorLGCtx *ctx)
4626 {
4627   PetscDraw      draw;
4628   PetscErrorCode ierr;
4629 
4630   PetscFunctionBegin;
4631   ierr = PetscNew(ctx);CHKERRQ(ierr);
4632   ierr = PetscDrawCreate(comm,host,label,x,y,m,n,&draw);CHKERRQ(ierr);
4633   ierr = PetscDrawSetFromOptions(draw);CHKERRQ(ierr);
4634   ierr = PetscDrawLGCreate(draw,1,&(*ctx)->lg);CHKERRQ(ierr);
4635   ierr = PetscDrawLGSetFromOptions((*ctx)->lg);CHKERRQ(ierr);
4636   ierr = PetscDrawDestroy(&draw);CHKERRQ(ierr);
4637   (*ctx)->howoften = howoften;
4638   PetscFunctionReturn(0);
4639 }
4640 
4641 PetscErrorCode TSMonitorLGTimeStep(TS ts,PetscInt step,PetscReal ptime,Vec v,void *monctx)
4642 {
4643   TSMonitorLGCtx ctx = (TSMonitorLGCtx) monctx;
4644   PetscReal      x   = ptime,y;
4645   PetscErrorCode ierr;
4646 
4647   PetscFunctionBegin;
4648   if (step < 0) PetscFunctionReturn(0); /* -1 indicates an interpolated solution */
4649   if (!step) {
4650     PetscDrawAxis axis;
4651     const char *ylabel = ctx->semilogy ? "Log Time Step" : "Time Step";
4652     ierr = PetscDrawLGGetAxis(ctx->lg,&axis);CHKERRQ(ierr);
4653     ierr = PetscDrawAxisSetLabels(axis,"Timestep as function of time","Time",ylabel);CHKERRQ(ierr);
4654     ierr = PetscDrawLGReset(ctx->lg);CHKERRQ(ierr);
4655   }
4656   ierr = TSGetTimeStep(ts,&y);CHKERRQ(ierr);
4657   if (ctx->semilogy) y = PetscLog10Real(y);
4658   ierr = PetscDrawLGAddPoint(ctx->lg,&x,&y);CHKERRQ(ierr);
4659   if (((ctx->howoften > 0) && (!(step % ctx->howoften))) || ((ctx->howoften == -1) && ts->reason)) {
4660     ierr = PetscDrawLGDraw(ctx->lg);CHKERRQ(ierr);
4661     ierr = PetscDrawLGSave(ctx->lg);CHKERRQ(ierr);
4662   }
4663   PetscFunctionReturn(0);
4664 }
4665 
4666 /*@C
4667    TSMonitorLGCtxDestroy - Destroys a line graph context that was created
4668    with TSMonitorLGCtxCreate().
4669 
4670    Collective on TSMonitorLGCtx
4671 
4672    Input Parameter:
4673 .  ctx - the monitor context
4674 
4675    Level: intermediate
4676 
4677 .keywords: TS, monitor, line graph, destroy
4678 
4679 .seealso: TSMonitorLGCtxCreate(),  TSMonitorSet(), TSMonitorLGTimeStep();
4680 @*/
4681 PetscErrorCode  TSMonitorLGCtxDestroy(TSMonitorLGCtx *ctx)
4682 {
4683   PetscErrorCode ierr;
4684 
4685   PetscFunctionBegin;
4686   if ((*ctx)->transformdestroy) {
4687     ierr = ((*ctx)->transformdestroy)((*ctx)->transformctx);CHKERRQ(ierr);
4688   }
4689   ierr = PetscDrawLGDestroy(&(*ctx)->lg);CHKERRQ(ierr);
4690   ierr = PetscStrArrayDestroy(&(*ctx)->names);CHKERRQ(ierr);
4691   ierr = PetscStrArrayDestroy(&(*ctx)->displaynames);CHKERRQ(ierr);
4692   ierr = PetscFree((*ctx)->displayvariables);CHKERRQ(ierr);
4693   ierr = PetscFree((*ctx)->displayvalues);CHKERRQ(ierr);
4694   ierr = PetscFree(*ctx);CHKERRQ(ierr);
4695   PetscFunctionReturn(0);
4696 }
4697 
4698 /*@
4699    TSGetTime - Gets the time of the most recently completed step.
4700 
4701    Not Collective
4702 
4703    Input Parameter:
4704 .  ts - the TS context obtained from TSCreate()
4705 
4706    Output Parameter:
4707 .  t  - the current time. This time may not corresponds to the final time set with TSSetMaxTime(), use TSGetSolveTime().
4708 
4709    Level: beginner
4710 
4711    Note:
4712    When called during time step evaluation (e.g. during residual evaluation or via hooks set using TSSetPreStep(),
4713    TSSetPreStage(), TSSetPostStage(), or TSSetPostStep()), the time is the time at the start of the step being evaluated.
4714 
4715 .seealso:  TSGetSolveTime(), TSSetTime(), TSGetTimeStep()
4716 
4717 .keywords: TS, get, time
4718 @*/
4719 PetscErrorCode  TSGetTime(TS ts,PetscReal *t)
4720 {
4721   PetscFunctionBegin;
4722   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
4723   PetscValidRealPointer(t,2);
4724   *t = ts->ptime;
4725   PetscFunctionReturn(0);
4726 }
4727 
4728 /*@
4729    TSGetPrevTime - Gets the starting time of the previously completed step.
4730 
4731    Not Collective
4732 
4733    Input Parameter:
4734 .  ts - the TS context obtained from TSCreate()
4735 
4736    Output Parameter:
4737 .  t  - the previous time
4738 
4739    Level: beginner
4740 
4741 .seealso: TSGetTime(), TSGetSolveTime(), TSGetTimeStep()
4742 
4743 .keywords: TS, get, time
4744 @*/
4745 PetscErrorCode  TSGetPrevTime(TS ts,PetscReal *t)
4746 {
4747   PetscFunctionBegin;
4748   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
4749   PetscValidRealPointer(t,2);
4750   *t = ts->ptime_prev;
4751   PetscFunctionReturn(0);
4752 }
4753 
4754 /*@
4755    TSSetTime - Allows one to reset the time.
4756 
4757    Logically Collective on TS
4758 
4759    Input Parameters:
4760 +  ts - the TS context obtained from TSCreate()
4761 -  time - the time
4762 
4763    Level: intermediate
4764 
4765 .seealso: TSGetTime(), TSSetMaxSteps()
4766 
4767 .keywords: TS, set, time
4768 @*/
4769 PetscErrorCode  TSSetTime(TS ts, PetscReal t)
4770 {
4771   PetscFunctionBegin;
4772   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
4773   PetscValidLogicalCollectiveReal(ts,t,2);
4774   ts->ptime = t;
4775   PetscFunctionReturn(0);
4776 }
4777 
4778 /*@C
4779    TSSetOptionsPrefix - Sets the prefix used for searching for all
4780    TS options in the database.
4781 
4782    Logically Collective on TS
4783 
4784    Input Parameter:
4785 +  ts     - The TS context
4786 -  prefix - The prefix to prepend to all option names
4787 
4788    Notes:
4789    A hyphen (-) must NOT be given at the beginning of the prefix name.
4790    The first character of all runtime options is AUTOMATICALLY the
4791    hyphen.
4792 
4793    Level: advanced
4794 
4795 .keywords: TS, set, options, prefix, database
4796 
4797 .seealso: TSSetFromOptions()
4798 
4799 @*/
4800 PetscErrorCode  TSSetOptionsPrefix(TS ts,const char prefix[])
4801 {
4802   PetscErrorCode ierr;
4803   SNES           snes;
4804 
4805   PetscFunctionBegin;
4806   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
4807   ierr = PetscObjectSetOptionsPrefix((PetscObject)ts,prefix);CHKERRQ(ierr);
4808   ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr);
4809   ierr = SNESSetOptionsPrefix(snes,prefix);CHKERRQ(ierr);
4810   PetscFunctionReturn(0);
4811 }
4812 
4813 /*@C
4814    TSAppendOptionsPrefix - Appends to the prefix used for searching for all
4815    TS options in the database.
4816 
4817    Logically Collective on TS
4818 
4819    Input Parameter:
4820 +  ts     - The TS context
4821 -  prefix - The prefix to prepend to all option names
4822 
4823    Notes:
4824    A hyphen (-) must NOT be given at the beginning of the prefix name.
4825    The first character of all runtime options is AUTOMATICALLY the
4826    hyphen.
4827 
4828    Level: advanced
4829 
4830 .keywords: TS, append, options, prefix, database
4831 
4832 .seealso: TSGetOptionsPrefix()
4833 
4834 @*/
4835 PetscErrorCode  TSAppendOptionsPrefix(TS ts,const char prefix[])
4836 {
4837   PetscErrorCode ierr;
4838   SNES           snes;
4839 
4840   PetscFunctionBegin;
4841   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
4842   ierr = PetscObjectAppendOptionsPrefix((PetscObject)ts,prefix);CHKERRQ(ierr);
4843   ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr);
4844   ierr = SNESAppendOptionsPrefix(snes,prefix);CHKERRQ(ierr);
4845   PetscFunctionReturn(0);
4846 }
4847 
4848 /*@C
4849    TSGetOptionsPrefix - Sets the prefix used for searching for all
4850    TS options in the database.
4851 
4852    Not Collective
4853 
4854    Input Parameter:
4855 .  ts - The TS context
4856 
4857    Output Parameter:
4858 .  prefix - A pointer to the prefix string used
4859 
4860    Notes: On the fortran side, the user should pass in a string 'prifix' of
4861    sufficient length to hold the prefix.
4862 
4863    Level: intermediate
4864 
4865 .keywords: TS, get, options, prefix, database
4866 
4867 .seealso: TSAppendOptionsPrefix()
4868 @*/
4869 PetscErrorCode  TSGetOptionsPrefix(TS ts,const char *prefix[])
4870 {
4871   PetscErrorCode ierr;
4872 
4873   PetscFunctionBegin;
4874   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
4875   PetscValidPointer(prefix,2);
4876   ierr = PetscObjectGetOptionsPrefix((PetscObject)ts,prefix);CHKERRQ(ierr);
4877   PetscFunctionReturn(0);
4878 }
4879 
4880 /*@C
4881    TSGetRHSJacobian - Returns the Jacobian J at the present timestep.
4882 
4883    Not Collective, but parallel objects are returned if TS is parallel
4884 
4885    Input Parameter:
4886 .  ts  - The TS context obtained from TSCreate()
4887 
4888    Output Parameters:
4889 +  Amat - The (approximate) Jacobian J of G, where U_t = G(U,t)  (or NULL)
4890 .  Pmat - The matrix from which the preconditioner is constructed, usually the same as Amat  (or NULL)
4891 .  func - Function to compute the Jacobian of the RHS  (or NULL)
4892 -  ctx - User-defined context for Jacobian evaluation routine  (or NULL)
4893 
4894    Notes: You can pass in NULL for any return argument you do not need.
4895 
4896    Level: intermediate
4897 
4898 .seealso: TSGetTimeStep(), TSGetMatrices(), TSGetTime(), TSGetStepNumber()
4899 
4900 .keywords: TS, timestep, get, matrix, Jacobian
4901 @*/
4902 PetscErrorCode  TSGetRHSJacobian(TS ts,Mat *Amat,Mat *Pmat,TSRHSJacobian *func,void **ctx)
4903 {
4904   PetscErrorCode ierr;
4905   DM             dm;
4906 
4907   PetscFunctionBegin;
4908   if (Amat || Pmat) {
4909     SNES snes;
4910     ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr);
4911     ierr = SNESSetUpMatrices(snes);CHKERRQ(ierr);
4912     ierr = SNESGetJacobian(snes,Amat,Pmat,NULL,NULL);CHKERRQ(ierr);
4913   }
4914   ierr = TSGetDM(ts,&dm);CHKERRQ(ierr);
4915   ierr = DMTSGetRHSJacobian(dm,func,ctx);CHKERRQ(ierr);
4916   PetscFunctionReturn(0);
4917 }
4918 
4919 /*@C
4920    TSGetIJacobian - Returns the implicit Jacobian at the present timestep.
4921 
4922    Not Collective, but parallel objects are returned if TS is parallel
4923 
4924    Input Parameter:
4925 .  ts  - The TS context obtained from TSCreate()
4926 
4927    Output Parameters:
4928 +  Amat  - The (approximate) Jacobian of F(t,U,U_t)
4929 .  Pmat - The matrix from which the preconditioner is constructed, often the same as Amat
4930 .  f   - The function to compute the matrices
4931 - ctx - User-defined context for Jacobian evaluation routine
4932 
4933    Notes: You can pass in NULL for any return argument you do not need.
4934 
4935    Level: advanced
4936 
4937 .seealso: TSGetTimeStep(), TSGetRHSJacobian(), TSGetMatrices(), TSGetTime(), TSGetStepNumber()
4938 
4939 .keywords: TS, timestep, get, matrix, Jacobian
4940 @*/
4941 PetscErrorCode  TSGetIJacobian(TS ts,Mat *Amat,Mat *Pmat,TSIJacobian *f,void **ctx)
4942 {
4943   PetscErrorCode ierr;
4944   DM             dm;
4945 
4946   PetscFunctionBegin;
4947   if (Amat || Pmat) {
4948     SNES snes;
4949     ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr);
4950     ierr = SNESSetUpMatrices(snes);CHKERRQ(ierr);
4951     ierr = SNESGetJacobian(snes,Amat,Pmat,NULL,NULL);CHKERRQ(ierr);
4952   }
4953   ierr = TSGetDM(ts,&dm);CHKERRQ(ierr);
4954   ierr = DMTSGetIJacobian(dm,f,ctx);CHKERRQ(ierr);
4955   PetscFunctionReturn(0);
4956 }
4957 
4958 /*@C
4959    TSMonitorDrawSolution - Monitors progress of the TS solvers by calling
4960    VecView() for the solution at each timestep
4961 
4962    Collective on TS
4963 
4964    Input Parameters:
4965 +  ts - the TS context
4966 .  step - current time-step
4967 .  ptime - current time
4968 -  dummy - either a viewer or NULL
4969 
4970    Options Database:
4971 .   -ts_monitor_draw_solution_initial - show initial solution as well as current solution
4972 
4973    Notes: the initial solution and current solution are not display with a common axis scaling so generally the option -ts_monitor_draw_solution_initial
4974        will look bad
4975 
4976    Level: intermediate
4977 
4978 .keywords: TS,  vector, monitor, view
4979 
4980 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView()
4981 @*/
4982 PetscErrorCode  TSMonitorDrawSolution(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dummy)
4983 {
4984   PetscErrorCode   ierr;
4985   TSMonitorDrawCtx ictx = (TSMonitorDrawCtx)dummy;
4986   PetscDraw        draw;
4987 
4988   PetscFunctionBegin;
4989   if (!step && ictx->showinitial) {
4990     if (!ictx->initialsolution) {
4991       ierr = VecDuplicate(u,&ictx->initialsolution);CHKERRQ(ierr);
4992     }
4993     ierr = VecCopy(u,ictx->initialsolution);CHKERRQ(ierr);
4994   }
4995   if (!(((ictx->howoften > 0) && (!(step % ictx->howoften))) || ((ictx->howoften == -1) && ts->reason))) PetscFunctionReturn(0);
4996 
4997   if (ictx->showinitial) {
4998     PetscReal pause;
4999     ierr = PetscViewerDrawGetPause(ictx->viewer,&pause);CHKERRQ(ierr);
5000     ierr = PetscViewerDrawSetPause(ictx->viewer,0.0);CHKERRQ(ierr);
5001     ierr = VecView(ictx->initialsolution,ictx->viewer);CHKERRQ(ierr);
5002     ierr = PetscViewerDrawSetPause(ictx->viewer,pause);CHKERRQ(ierr);
5003     ierr = PetscViewerDrawSetHold(ictx->viewer,PETSC_TRUE);CHKERRQ(ierr);
5004   }
5005   ierr = VecView(u,ictx->viewer);CHKERRQ(ierr);
5006   if (ictx->showtimestepandtime) {
5007     PetscReal xl,yl,xr,yr,h;
5008     char      time[32];
5009 
5010     ierr = PetscViewerDrawGetDraw(ictx->viewer,0,&draw);CHKERRQ(ierr);
5011     ierr = PetscSNPrintf(time,32,"Timestep %d Time %g",(int)step,(double)ptime);CHKERRQ(ierr);
5012     ierr = PetscDrawGetCoordinates(draw,&xl,&yl,&xr,&yr);CHKERRQ(ierr);
5013     h    = yl + .95*(yr - yl);
5014     ierr = PetscDrawStringCentered(draw,.5*(xl+xr),h,PETSC_DRAW_BLACK,time);CHKERRQ(ierr);
5015     ierr = PetscDrawFlush(draw);CHKERRQ(ierr);
5016   }
5017 
5018   if (ictx->showinitial) {
5019     ierr = PetscViewerDrawSetHold(ictx->viewer,PETSC_FALSE);CHKERRQ(ierr);
5020   }
5021   PetscFunctionReturn(0);
5022 }
5023 
5024 /*@C
5025    TSAdjointMonitorDrawSensi - Monitors progress of the adjoint TS solvers by calling
5026    VecView() for the sensitivities to initial states at each timestep
5027 
5028    Collective on TS
5029 
5030    Input Parameters:
5031 +  ts - the TS context
5032 .  step - current time-step
5033 .  ptime - current time
5034 .  u - current state
5035 .  numcost - number of cost functions
5036 .  lambda - sensitivities to initial conditions
5037 .  mu - sensitivities to parameters
5038 -  dummy - either a viewer or NULL
5039 
5040    Level: intermediate
5041 
5042 .keywords: TS,  vector, adjoint, monitor, view
5043 
5044 .seealso: TSAdjointMonitorSet(), TSAdjointMonitorDefault(), VecView()
5045 @*/
5046 PetscErrorCode  TSAdjointMonitorDrawSensi(TS ts,PetscInt step,PetscReal ptime,Vec u,PetscInt numcost,Vec *lambda,Vec *mu,void *dummy)
5047 {
5048   PetscErrorCode   ierr;
5049   TSMonitorDrawCtx ictx = (TSMonitorDrawCtx)dummy;
5050   PetscDraw        draw;
5051   PetscReal        xl,yl,xr,yr,h;
5052   char             time[32];
5053 
5054   PetscFunctionBegin;
5055   if (!(((ictx->howoften > 0) && (!(step % ictx->howoften))) || ((ictx->howoften == -1) && ts->reason))) PetscFunctionReturn(0);
5056 
5057   ierr = VecView(lambda[0],ictx->viewer);CHKERRQ(ierr);
5058   ierr = PetscViewerDrawGetDraw(ictx->viewer,0,&draw);CHKERRQ(ierr);
5059   ierr = PetscSNPrintf(time,32,"Timestep %d Time %g",(int)step,(double)ptime);CHKERRQ(ierr);
5060   ierr = PetscDrawGetCoordinates(draw,&xl,&yl,&xr,&yr);CHKERRQ(ierr);
5061   h    = yl + .95*(yr - yl);
5062   ierr = PetscDrawStringCentered(draw,.5*(xl+xr),h,PETSC_DRAW_BLACK,time);CHKERRQ(ierr);
5063   ierr = PetscDrawFlush(draw);CHKERRQ(ierr);
5064   PetscFunctionReturn(0);
5065 }
5066 
5067 /*@C
5068    TSMonitorDrawSolutionPhase - Monitors progress of the TS solvers by plotting the solution as a phase diagram
5069 
5070    Collective on TS
5071 
5072    Input Parameters:
5073 +  ts - the TS context
5074 .  step - current time-step
5075 .  ptime - current time
5076 -  dummy - either a viewer or NULL
5077 
5078    Level: intermediate
5079 
5080 .keywords: TS,  vector, monitor, view
5081 
5082 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView()
5083 @*/
5084 PetscErrorCode  TSMonitorDrawSolutionPhase(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dummy)
5085 {
5086   PetscErrorCode    ierr;
5087   TSMonitorDrawCtx  ictx = (TSMonitorDrawCtx)dummy;
5088   PetscDraw         draw;
5089   PetscDrawAxis     axis;
5090   PetscInt          n;
5091   PetscMPIInt       size;
5092   PetscReal         U0,U1,xl,yl,xr,yr,h;
5093   char              time[32];
5094   const PetscScalar *U;
5095 
5096   PetscFunctionBegin;
5097   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)ts),&size);CHKERRQ(ierr);
5098   if (size != 1) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"Only allowed for sequential runs");
5099   ierr = VecGetSize(u,&n);CHKERRQ(ierr);
5100   if (n != 2) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"Only for ODEs with two unknowns");
5101 
5102   ierr = PetscViewerDrawGetDraw(ictx->viewer,0,&draw);CHKERRQ(ierr);
5103   ierr = PetscViewerDrawGetDrawAxis(ictx->viewer,0,&axis);CHKERRQ(ierr);
5104   ierr = PetscDrawAxisGetLimits(axis,&xl,&xr,&yl,&yr);CHKERRQ(ierr);
5105   if (!step) {
5106     ierr = PetscDrawClear(draw);CHKERRQ(ierr);
5107     ierr = PetscDrawAxisDraw(axis);CHKERRQ(ierr);
5108   }
5109 
5110   ierr = VecGetArrayRead(u,&U);CHKERRQ(ierr);
5111   U0 = PetscRealPart(U[0]);
5112   U1 = PetscRealPart(U[1]);
5113   ierr = VecRestoreArrayRead(u,&U);CHKERRQ(ierr);
5114   if ((U0 < xl) || (U1 < yl) || (U0 > xr) || (U1 > yr)) PetscFunctionReturn(0);
5115 
5116   ierr = PetscDrawCollectiveBegin(draw);CHKERRQ(ierr);
5117   ierr = PetscDrawPoint(draw,U0,U1,PETSC_DRAW_BLACK);CHKERRQ(ierr);
5118   if (ictx->showtimestepandtime) {
5119     ierr = PetscDrawGetCoordinates(draw,&xl,&yl,&xr,&yr);CHKERRQ(ierr);
5120     ierr = PetscSNPrintf(time,32,"Timestep %d Time %g",(int)step,(double)ptime);CHKERRQ(ierr);
5121     h    = yl + .95*(yr - yl);
5122     ierr = PetscDrawStringCentered(draw,.5*(xl+xr),h,PETSC_DRAW_BLACK,time);CHKERRQ(ierr);
5123   }
5124   ierr = PetscDrawCollectiveEnd(draw);CHKERRQ(ierr);
5125   ierr = PetscDrawFlush(draw);CHKERRQ(ierr);
5126   ierr = PetscDrawPause(draw);CHKERRQ(ierr);
5127   ierr = PetscDrawSave(draw);CHKERRQ(ierr);
5128   PetscFunctionReturn(0);
5129 }
5130 
5131 /*@C
5132    TSMonitorDrawCtxDestroy - Destroys the monitor context for TSMonitorDrawSolution()
5133 
5134    Collective on TS
5135 
5136    Input Parameters:
5137 .    ctx - the monitor context
5138 
5139    Level: intermediate
5140 
5141 .keywords: TS,  vector, monitor, view
5142 
5143 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorDrawSolution(), TSMonitorDrawError()
5144 @*/
5145 PetscErrorCode  TSMonitorDrawCtxDestroy(TSMonitorDrawCtx *ictx)
5146 {
5147   PetscErrorCode ierr;
5148 
5149   PetscFunctionBegin;
5150   ierr = PetscViewerDestroy(&(*ictx)->viewer);CHKERRQ(ierr);
5151   ierr = VecDestroy(&(*ictx)->initialsolution);CHKERRQ(ierr);
5152   ierr = PetscFree(*ictx);CHKERRQ(ierr);
5153   PetscFunctionReturn(0);
5154 }
5155 
5156 /*@C
5157    TSMonitorDrawCtxCreate - Creates the monitor context for TSMonitorDrawCtx
5158 
5159    Collective on TS
5160 
5161    Input Parameter:
5162 .    ts - time-step context
5163 
5164    Output Patameter:
5165 .    ctx - the monitor context
5166 
5167    Options Database:
5168 .   -ts_monitor_draw_solution_initial - show initial solution as well as current solution
5169 
5170    Level: intermediate
5171 
5172 .keywords: TS,  vector, monitor, view
5173 
5174 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorDrawCtx()
5175 @*/
5176 PetscErrorCode  TSMonitorDrawCtxCreate(MPI_Comm comm,const char host[],const char label[],int x,int y,int m,int n,PetscInt howoften,TSMonitorDrawCtx *ctx)
5177 {
5178   PetscErrorCode   ierr;
5179 
5180   PetscFunctionBegin;
5181   ierr = PetscNew(ctx);CHKERRQ(ierr);
5182   ierr = PetscViewerDrawOpen(comm,host,label,x,y,m,n,&(*ctx)->viewer);CHKERRQ(ierr);
5183   ierr = PetscViewerSetFromOptions((*ctx)->viewer);CHKERRQ(ierr);
5184 
5185   (*ctx)->howoften    = howoften;
5186   (*ctx)->showinitial = PETSC_FALSE;
5187   ierr = PetscOptionsGetBool(NULL,NULL,"-ts_monitor_draw_solution_initial",&(*ctx)->showinitial,NULL);CHKERRQ(ierr);
5188 
5189   (*ctx)->showtimestepandtime = PETSC_FALSE;
5190   ierr = PetscOptionsGetBool(NULL,NULL,"-ts_monitor_draw_solution_show_time",&(*ctx)->showtimestepandtime,NULL);CHKERRQ(ierr);
5191   PetscFunctionReturn(0);
5192 }
5193 
5194 /*@C
5195    TSMonitorDrawError - Monitors progress of the TS solvers by calling
5196    VecView() for the error at each timestep
5197 
5198    Collective on TS
5199 
5200    Input Parameters:
5201 +  ts - the TS context
5202 .  step - current time-step
5203 .  ptime - current time
5204 -  dummy - either a viewer or NULL
5205 
5206    Level: intermediate
5207 
5208 .keywords: TS,  vector, monitor, view
5209 
5210 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView()
5211 @*/
5212 PetscErrorCode  TSMonitorDrawError(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dummy)
5213 {
5214   PetscErrorCode   ierr;
5215   TSMonitorDrawCtx ctx    = (TSMonitorDrawCtx)dummy;
5216   PetscViewer      viewer = ctx->viewer;
5217   Vec              work;
5218 
5219   PetscFunctionBegin;
5220   if (!(((ctx->howoften > 0) && (!(step % ctx->howoften))) || ((ctx->howoften == -1) && ts->reason))) PetscFunctionReturn(0);
5221   ierr = VecDuplicate(u,&work);CHKERRQ(ierr);
5222   ierr = TSComputeSolutionFunction(ts,ptime,work);CHKERRQ(ierr);
5223   ierr = VecAXPY(work,-1.0,u);CHKERRQ(ierr);
5224   ierr = VecView(work,viewer);CHKERRQ(ierr);
5225   ierr = VecDestroy(&work);CHKERRQ(ierr);
5226   PetscFunctionReturn(0);
5227 }
5228 
5229 #include <petsc/private/dmimpl.h>
5230 /*@
5231    TSSetDM - Sets the DM that may be used by some nonlinear solvers or preconditioners under the TS
5232 
5233    Logically Collective on TS and DM
5234 
5235    Input Parameters:
5236 +  ts - the ODE integrator object
5237 -  dm - the dm, cannot be NULL
5238 
5239    Level: intermediate
5240 
5241 .seealso: TSGetDM(), SNESSetDM(), SNESGetDM()
5242 @*/
5243 PetscErrorCode  TSSetDM(TS ts,DM dm)
5244 {
5245   PetscErrorCode ierr;
5246   SNES           snes;
5247   DMTS           tsdm;
5248 
5249   PetscFunctionBegin;
5250   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
5251   PetscValidHeaderSpecific(dm,DM_CLASSID,2);
5252   ierr = PetscObjectReference((PetscObject)dm);CHKERRQ(ierr);
5253   if (ts->dm) {               /* Move the DMTS context over to the new DM unless the new DM already has one */
5254     if (ts->dm->dmts && !dm->dmts) {
5255       ierr = DMCopyDMTS(ts->dm,dm);CHKERRQ(ierr);
5256       ierr = DMGetDMTS(ts->dm,&tsdm);CHKERRQ(ierr);
5257       if (tsdm->originaldm == ts->dm) { /* Grant write privileges to the replacement DM */
5258         tsdm->originaldm = dm;
5259       }
5260     }
5261     ierr = DMDestroy(&ts->dm);CHKERRQ(ierr);
5262   }
5263   ts->dm = dm;
5264 
5265   ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr);
5266   ierr = SNESSetDM(snes,dm);CHKERRQ(ierr);
5267   PetscFunctionReturn(0);
5268 }
5269 
5270 /*@
5271    TSGetDM - Gets the DM that may be used by some preconditioners
5272 
5273    Not Collective
5274 
5275    Input Parameter:
5276 . ts - the preconditioner context
5277 
5278    Output Parameter:
5279 .  dm - the dm
5280 
5281    Level: intermediate
5282 
5283 .seealso: TSSetDM(), SNESSetDM(), SNESGetDM()
5284 @*/
5285 PetscErrorCode  TSGetDM(TS ts,DM *dm)
5286 {
5287   PetscErrorCode ierr;
5288 
5289   PetscFunctionBegin;
5290   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
5291   if (!ts->dm) {
5292     ierr = DMShellCreate(PetscObjectComm((PetscObject)ts),&ts->dm);CHKERRQ(ierr);
5293     if (ts->snes) {ierr = SNESSetDM(ts->snes,ts->dm);CHKERRQ(ierr);}
5294   }
5295   *dm = ts->dm;
5296   PetscFunctionReturn(0);
5297 }
5298 
5299 /*@
5300    SNESTSFormFunction - Function to evaluate nonlinear residual
5301 
5302    Logically Collective on SNES
5303 
5304    Input Parameter:
5305 + snes - nonlinear solver
5306 . U - the current state at which to evaluate the residual
5307 - ctx - user context, must be a TS
5308 
5309    Output Parameter:
5310 . F - the nonlinear residual
5311 
5312    Notes:
5313    This function is not normally called by users and is automatically registered with the SNES used by TS.
5314    It is most frequently passed to MatFDColoringSetFunction().
5315 
5316    Level: advanced
5317 
5318 .seealso: SNESSetFunction(), MatFDColoringSetFunction()
5319 @*/
5320 PetscErrorCode  SNESTSFormFunction(SNES snes,Vec U,Vec F,void *ctx)
5321 {
5322   TS             ts = (TS)ctx;
5323   PetscErrorCode ierr;
5324 
5325   PetscFunctionBegin;
5326   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
5327   PetscValidHeaderSpecific(U,VEC_CLASSID,2);
5328   PetscValidHeaderSpecific(F,VEC_CLASSID,3);
5329   PetscValidHeaderSpecific(ts,TS_CLASSID,4);
5330   ierr = (ts->ops->snesfunction)(snes,U,F,ts);CHKERRQ(ierr);
5331   PetscFunctionReturn(0);
5332 }
5333 
5334 /*@
5335    SNESTSFormJacobian - Function to evaluate the Jacobian
5336 
5337    Collective on SNES
5338 
5339    Input Parameter:
5340 + snes - nonlinear solver
5341 . U - the current state at which to evaluate the residual
5342 - ctx - user context, must be a TS
5343 
5344    Output Parameter:
5345 + A - the Jacobian
5346 . B - the preconditioning matrix (may be the same as A)
5347 - flag - indicates any structure change in the matrix
5348 
5349    Notes:
5350    This function is not normally called by users and is automatically registered with the SNES used by TS.
5351 
5352    Level: developer
5353 
5354 .seealso: SNESSetJacobian()
5355 @*/
5356 PetscErrorCode  SNESTSFormJacobian(SNES snes,Vec U,Mat A,Mat B,void *ctx)
5357 {
5358   TS             ts = (TS)ctx;
5359   PetscErrorCode ierr;
5360 
5361   PetscFunctionBegin;
5362   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
5363   PetscValidHeaderSpecific(U,VEC_CLASSID,2);
5364   PetscValidPointer(A,3);
5365   PetscValidHeaderSpecific(A,MAT_CLASSID,3);
5366   PetscValidPointer(B,4);
5367   PetscValidHeaderSpecific(B,MAT_CLASSID,4);
5368   PetscValidHeaderSpecific(ts,TS_CLASSID,6);
5369   ierr = (ts->ops->snesjacobian)(snes,U,A,B,ts);CHKERRQ(ierr);
5370   PetscFunctionReturn(0);
5371 }
5372 
5373 /*@C
5374    TSComputeRHSFunctionLinear - Evaluate the right hand side via the user-provided Jacobian, for linear problems Udot = A U only
5375 
5376    Collective on TS
5377 
5378    Input Arguments:
5379 +  ts - time stepping context
5380 .  t - time at which to evaluate
5381 .  U - state at which to evaluate
5382 -  ctx - context
5383 
5384    Output Arguments:
5385 .  F - right hand side
5386 
5387    Level: intermediate
5388 
5389    Notes:
5390    This function is intended to be passed to TSSetRHSFunction() to evaluate the right hand side for linear problems.
5391    The matrix (and optionally the evaluation context) should be passed to TSSetRHSJacobian().
5392 
5393 .seealso: TSSetRHSFunction(), TSSetRHSJacobian(), TSComputeRHSJacobianConstant()
5394 @*/
5395 PetscErrorCode TSComputeRHSFunctionLinear(TS ts,PetscReal t,Vec U,Vec F,void *ctx)
5396 {
5397   PetscErrorCode ierr;
5398   Mat            Arhs,Brhs;
5399 
5400   PetscFunctionBegin;
5401   ierr = TSGetRHSMats_Private(ts,&Arhs,&Brhs);CHKERRQ(ierr);
5402   ierr = TSComputeRHSJacobian(ts,t,U,Arhs,Brhs);CHKERRQ(ierr);
5403   ierr = MatMult(Arhs,U,F);CHKERRQ(ierr);
5404   PetscFunctionReturn(0);
5405 }
5406 
5407 /*@C
5408    TSComputeRHSJacobianConstant - Reuses a Jacobian that is time-independent.
5409 
5410    Collective on TS
5411 
5412    Input Arguments:
5413 +  ts - time stepping context
5414 .  t - time at which to evaluate
5415 .  U - state at which to evaluate
5416 -  ctx - context
5417 
5418    Output Arguments:
5419 +  A - pointer to operator
5420 .  B - pointer to preconditioning matrix
5421 -  flg - matrix structure flag
5422 
5423    Level: intermediate
5424 
5425    Notes:
5426    This function is intended to be passed to TSSetRHSJacobian() to evaluate the Jacobian for linear time-independent problems.
5427 
5428 .seealso: TSSetRHSFunction(), TSSetRHSJacobian(), TSComputeRHSFunctionLinear()
5429 @*/
5430 PetscErrorCode TSComputeRHSJacobianConstant(TS ts,PetscReal t,Vec U,Mat A,Mat B,void *ctx)
5431 {
5432   PetscFunctionBegin;
5433   PetscFunctionReturn(0);
5434 }
5435 
5436 /*@C
5437    TSComputeIFunctionLinear - Evaluate the left hand side via the user-provided Jacobian, for linear problems only
5438 
5439    Collective on TS
5440 
5441    Input Arguments:
5442 +  ts - time stepping context
5443 .  t - time at which to evaluate
5444 .  U - state at which to evaluate
5445 .  Udot - time derivative of state vector
5446 -  ctx - context
5447 
5448    Output Arguments:
5449 .  F - left hand side
5450 
5451    Level: intermediate
5452 
5453    Notes:
5454    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
5455    user is required to write their own TSComputeIFunction.
5456    This function is intended to be passed to TSSetIFunction() to evaluate the left hand side for linear problems.
5457    The matrix (and optionally the evaluation context) should be passed to TSSetIJacobian().
5458 
5459    Note that using this function is NOT equivalent to using TSComputeRHSFunctionLinear() since that solves Udot = A U
5460 
5461 .seealso: TSSetIFunction(), TSSetIJacobian(), TSComputeIJacobianConstant(), TSComputeRHSFunctionLinear()
5462 @*/
5463 PetscErrorCode TSComputeIFunctionLinear(TS ts,PetscReal t,Vec U,Vec Udot,Vec F,void *ctx)
5464 {
5465   PetscErrorCode ierr;
5466   Mat            A,B;
5467 
5468   PetscFunctionBegin;
5469   ierr = TSGetIJacobian(ts,&A,&B,NULL,NULL);CHKERRQ(ierr);
5470   ierr = TSComputeIJacobian(ts,t,U,Udot,1.0,A,B,PETSC_TRUE);CHKERRQ(ierr);
5471   ierr = MatMult(A,Udot,F);CHKERRQ(ierr);
5472   PetscFunctionReturn(0);
5473 }
5474 
5475 /*@C
5476    TSComputeIJacobianConstant - Reuses a time-independent for a semi-implicit DAE or ODE
5477 
5478    Collective on TS
5479 
5480    Input Arguments:
5481 +  ts - time stepping context
5482 .  t - time at which to evaluate
5483 .  U - state at which to evaluate
5484 .  Udot - time derivative of state vector
5485 .  shift - shift to apply
5486 -  ctx - context
5487 
5488    Output Arguments:
5489 +  A - pointer to operator
5490 .  B - pointer to preconditioning matrix
5491 -  flg - matrix structure flag
5492 
5493    Level: advanced
5494 
5495    Notes:
5496    This function is intended to be passed to TSSetIJacobian() to evaluate the Jacobian for linear time-independent problems.
5497 
5498    It is only appropriate for problems of the form
5499 
5500 $     M Udot = F(U,t)
5501 
5502   where M is constant and F is non-stiff.  The user must pass M to TSSetIJacobian().  The current implementation only
5503   works with IMEX time integration methods such as TSROSW and TSARKIMEX, since there is no support for de-constructing
5504   an implicit operator of the form
5505 
5506 $    shift*M + J
5507 
5508   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
5509   a copy of M or reassemble it when requested.
5510 
5511 .seealso: TSSetIFunction(), TSSetIJacobian(), TSComputeIFunctionLinear()
5512 @*/
5513 PetscErrorCode TSComputeIJacobianConstant(TS ts,PetscReal t,Vec U,Vec Udot,PetscReal shift,Mat A,Mat B,void *ctx)
5514 {
5515   PetscErrorCode ierr;
5516 
5517   PetscFunctionBegin;
5518   ierr = MatScale(A, shift / ts->ijacobian.shift);CHKERRQ(ierr);
5519   ts->ijacobian.shift = shift;
5520   PetscFunctionReturn(0);
5521 }
5522 
5523 /*@
5524    TSGetEquationType - Gets the type of the equation that TS is solving.
5525 
5526    Not Collective
5527 
5528    Input Parameter:
5529 .  ts - the TS context
5530 
5531    Output Parameter:
5532 .  equation_type - see TSEquationType
5533 
5534    Level: beginner
5535 
5536 .keywords: TS, equation type
5537 
5538 .seealso: TSSetEquationType(), TSEquationType
5539 @*/
5540 PetscErrorCode  TSGetEquationType(TS ts,TSEquationType *equation_type)
5541 {
5542   PetscFunctionBegin;
5543   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
5544   PetscValidPointer(equation_type,2);
5545   *equation_type = ts->equation_type;
5546   PetscFunctionReturn(0);
5547 }
5548 
5549 /*@
5550    TSSetEquationType - Sets the type of the equation that TS is solving.
5551 
5552    Not Collective
5553 
5554    Input Parameter:
5555 +  ts - the TS context
5556 -  equation_type - see TSEquationType
5557 
5558    Level: advanced
5559 
5560 .keywords: TS, equation type
5561 
5562 .seealso: TSGetEquationType(), TSEquationType
5563 @*/
5564 PetscErrorCode  TSSetEquationType(TS ts,TSEquationType equation_type)
5565 {
5566   PetscFunctionBegin;
5567   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
5568   ts->equation_type = equation_type;
5569   PetscFunctionReturn(0);
5570 }
5571 
5572 /*@
5573    TSGetConvergedReason - Gets the reason the TS iteration was stopped.
5574 
5575    Not Collective
5576 
5577    Input Parameter:
5578 .  ts - the TS context
5579 
5580    Output Parameter:
5581 .  reason - negative value indicates diverged, positive value converged, see TSConvergedReason or the
5582             manual pages for the individual convergence tests for complete lists
5583 
5584    Level: beginner
5585 
5586    Notes:
5587    Can only be called after the call to TSSolve() is complete.
5588 
5589 .keywords: TS, nonlinear, set, convergence, test
5590 
5591 .seealso: TSSetConvergenceTest(), TSConvergedReason
5592 @*/
5593 PetscErrorCode  TSGetConvergedReason(TS ts,TSConvergedReason *reason)
5594 {
5595   PetscFunctionBegin;
5596   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
5597   PetscValidPointer(reason,2);
5598   *reason = ts->reason;
5599   PetscFunctionReturn(0);
5600 }
5601 
5602 /*@
5603    TSSetConvergedReason - Sets the reason for handling the convergence of TSSolve.
5604 
5605    Not Collective
5606 
5607    Input Parameter:
5608 +  ts - the TS context
5609 .  reason - negative value indicates diverged, positive value converged, see TSConvergedReason or the
5610             manual pages for the individual convergence tests for complete lists
5611 
5612    Level: advanced
5613 
5614    Notes:
5615    Can only be called during TSSolve() is active.
5616 
5617 .keywords: TS, nonlinear, set, convergence, test
5618 
5619 .seealso: TSConvergedReason
5620 @*/
5621 PetscErrorCode  TSSetConvergedReason(TS ts,TSConvergedReason reason)
5622 {
5623   PetscFunctionBegin;
5624   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
5625   ts->reason = reason;
5626   PetscFunctionReturn(0);
5627 }
5628 
5629 /*@
5630    TSGetSolveTime - Gets the time after a call to TSSolve()
5631 
5632    Not Collective
5633 
5634    Input Parameter:
5635 .  ts - the TS context
5636 
5637    Output Parameter:
5638 .  ftime - the final time. This time corresponds to the final time set with TSSetMaxTime()
5639 
5640    Level: beginner
5641 
5642    Notes:
5643    Can only be called after the call to TSSolve() is complete.
5644 
5645 .keywords: TS, nonlinear, set, convergence, test
5646 
5647 .seealso: TSSetConvergenceTest(), TSConvergedReason
5648 @*/
5649 PetscErrorCode  TSGetSolveTime(TS ts,PetscReal *ftime)
5650 {
5651   PetscFunctionBegin;
5652   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
5653   PetscValidPointer(ftime,2);
5654   *ftime = ts->solvetime;
5655   PetscFunctionReturn(0);
5656 }
5657 
5658 /*@
5659    TSGetSNESIterations - Gets the total number of nonlinear iterations
5660    used by the time integrator.
5661 
5662    Not Collective
5663 
5664    Input Parameter:
5665 .  ts - TS context
5666 
5667    Output Parameter:
5668 .  nits - number of nonlinear iterations
5669 
5670    Notes:
5671    This counter is reset to zero for each successive call to TSSolve().
5672 
5673    Level: intermediate
5674 
5675 .keywords: TS, get, number, nonlinear, iterations
5676 
5677 .seealso:  TSGetKSPIterations()
5678 @*/
5679 PetscErrorCode TSGetSNESIterations(TS ts,PetscInt *nits)
5680 {
5681   PetscFunctionBegin;
5682   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
5683   PetscValidIntPointer(nits,2);
5684   *nits = ts->snes_its;
5685   PetscFunctionReturn(0);
5686 }
5687 
5688 /*@
5689    TSGetKSPIterations - Gets the total number of linear iterations
5690    used by the time integrator.
5691 
5692    Not Collective
5693 
5694    Input Parameter:
5695 .  ts - TS context
5696 
5697    Output Parameter:
5698 .  lits - number of linear iterations
5699 
5700    Notes:
5701    This counter is reset to zero for each successive call to TSSolve().
5702 
5703    Level: intermediate
5704 
5705 .keywords: TS, get, number, linear, iterations
5706 
5707 .seealso:  TSGetSNESIterations(), SNESGetKSPIterations()
5708 @*/
5709 PetscErrorCode TSGetKSPIterations(TS ts,PetscInt *lits)
5710 {
5711   PetscFunctionBegin;
5712   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
5713   PetscValidIntPointer(lits,2);
5714   *lits = ts->ksp_its;
5715   PetscFunctionReturn(0);
5716 }
5717 
5718 /*@
5719    TSGetStepRejections - Gets the total number of rejected steps.
5720 
5721    Not Collective
5722 
5723    Input Parameter:
5724 .  ts - TS context
5725 
5726    Output Parameter:
5727 .  rejects - number of steps rejected
5728 
5729    Notes:
5730    This counter is reset to zero for each successive call to TSSolve().
5731 
5732    Level: intermediate
5733 
5734 .keywords: TS, get, number
5735 
5736 .seealso:  TSGetSNESIterations(), TSGetKSPIterations(), TSSetMaxStepRejections(), TSGetSNESFailures(), TSSetMaxSNESFailures(), TSSetErrorIfStepFails()
5737 @*/
5738 PetscErrorCode TSGetStepRejections(TS ts,PetscInt *rejects)
5739 {
5740   PetscFunctionBegin;
5741   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
5742   PetscValidIntPointer(rejects,2);
5743   *rejects = ts->reject;
5744   PetscFunctionReturn(0);
5745 }
5746 
5747 /*@
5748    TSGetSNESFailures - Gets the total number of failed SNES solves
5749 
5750    Not Collective
5751 
5752    Input Parameter:
5753 .  ts - TS context
5754 
5755    Output Parameter:
5756 .  fails - number of failed nonlinear solves
5757 
5758    Notes:
5759    This counter is reset to zero for each successive call to TSSolve().
5760 
5761    Level: intermediate
5762 
5763 .keywords: TS, get, number
5764 
5765 .seealso:  TSGetSNESIterations(), TSGetKSPIterations(), TSSetMaxStepRejections(), TSGetStepRejections(), TSSetMaxSNESFailures()
5766 @*/
5767 PetscErrorCode TSGetSNESFailures(TS ts,PetscInt *fails)
5768 {
5769   PetscFunctionBegin;
5770   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
5771   PetscValidIntPointer(fails,2);
5772   *fails = ts->num_snes_failures;
5773   PetscFunctionReturn(0);
5774 }
5775 
5776 /*@
5777    TSSetMaxStepRejections - Sets the maximum number of step rejections before a step fails
5778 
5779    Not Collective
5780 
5781    Input Parameter:
5782 +  ts - TS context
5783 -  rejects - maximum number of rejected steps, pass -1 for unlimited
5784 
5785    Notes:
5786    The counter is reset to zero for each step
5787 
5788    Options Database Key:
5789  .  -ts_max_reject - Maximum number of step rejections before a step fails
5790 
5791    Level: intermediate
5792 
5793 .keywords: TS, set, maximum, number
5794 
5795 .seealso:  TSGetSNESIterations(), TSGetKSPIterations(), TSSetMaxSNESFailures(), TSGetStepRejections(), TSGetSNESFailures(), TSSetErrorIfStepFails(), TSGetConvergedReason()
5796 @*/
5797 PetscErrorCode TSSetMaxStepRejections(TS ts,PetscInt rejects)
5798 {
5799   PetscFunctionBegin;
5800   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
5801   ts->max_reject = rejects;
5802   PetscFunctionReturn(0);
5803 }
5804 
5805 /*@
5806    TSSetMaxSNESFailures - Sets the maximum number of failed SNES solves
5807 
5808    Not Collective
5809 
5810    Input Parameter:
5811 +  ts - TS context
5812 -  fails - maximum number of failed nonlinear solves, pass -1 for unlimited
5813 
5814    Notes:
5815    The counter is reset to zero for each successive call to TSSolve().
5816 
5817    Options Database Key:
5818  .  -ts_max_snes_failures - Maximum number of nonlinear solve failures
5819 
5820    Level: intermediate
5821 
5822 .keywords: TS, set, maximum, number
5823 
5824 .seealso:  TSGetSNESIterations(), TSGetKSPIterations(), TSSetMaxStepRejections(), TSGetStepRejections(), TSGetSNESFailures(), SNESGetConvergedReason(), TSGetConvergedReason()
5825 @*/
5826 PetscErrorCode TSSetMaxSNESFailures(TS ts,PetscInt fails)
5827 {
5828   PetscFunctionBegin;
5829   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
5830   ts->max_snes_failures = fails;
5831   PetscFunctionReturn(0);
5832 }
5833 
5834 /*@
5835    TSSetErrorIfStepFails - Error if no step succeeds
5836 
5837    Not Collective
5838 
5839    Input Parameter:
5840 +  ts - TS context
5841 -  err - PETSC_TRUE to error if no step succeeds, PETSC_FALSE to return without failure
5842 
5843    Options Database Key:
5844  .  -ts_error_if_step_fails - Error if no step succeeds
5845 
5846    Level: intermediate
5847 
5848 .keywords: TS, set, error
5849 
5850 .seealso:  TSGetSNESIterations(), TSGetKSPIterations(), TSSetMaxStepRejections(), TSGetStepRejections(), TSGetSNESFailures(), TSSetErrorIfStepFails(), TSGetConvergedReason()
5851 @*/
5852 PetscErrorCode TSSetErrorIfStepFails(TS ts,PetscBool err)
5853 {
5854   PetscFunctionBegin;
5855   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
5856   ts->errorifstepfailed = err;
5857   PetscFunctionReturn(0);
5858 }
5859 
5860 /*@C
5861    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
5862 
5863    Collective on TS
5864 
5865    Input Parameters:
5866 +  ts - the TS context
5867 .  step - current time-step
5868 .  ptime - current time
5869 .  u - current state
5870 -  vf - viewer and its format
5871 
5872    Level: intermediate
5873 
5874 .keywords: TS,  vector, monitor, view
5875 
5876 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView()
5877 @*/
5878 PetscErrorCode  TSMonitorSolution(TS ts,PetscInt step,PetscReal ptime,Vec u,PetscViewerAndFormat *vf)
5879 {
5880   PetscErrorCode ierr;
5881 
5882   PetscFunctionBegin;
5883   ierr = PetscViewerPushFormat(vf->viewer,vf->format);CHKERRQ(ierr);
5884   ierr = VecView(u,vf->viewer);CHKERRQ(ierr);
5885   ierr = PetscViewerPopFormat(vf->viewer);CHKERRQ(ierr);
5886   PetscFunctionReturn(0);
5887 }
5888 
5889 /*@C
5890    TSMonitorSolutionVTK - Monitors progress of the TS solvers by VecView() for the solution at each timestep.
5891 
5892    Collective on TS
5893 
5894    Input Parameters:
5895 +  ts - the TS context
5896 .  step - current time-step
5897 .  ptime - current time
5898 .  u - current state
5899 -  filenametemplate - string containing a format specifier for the integer time step (e.g. %03D)
5900 
5901    Level: intermediate
5902 
5903    Notes:
5904    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.
5905    These are named according to the file name template.
5906 
5907    This function is normally passed as an argument to TSMonitorSet() along with TSMonitorSolutionVTKDestroy().
5908 
5909 .keywords: TS,  vector, monitor, view
5910 
5911 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView()
5912 @*/
5913 PetscErrorCode TSMonitorSolutionVTK(TS ts,PetscInt step,PetscReal ptime,Vec u,void *filenametemplate)
5914 {
5915   PetscErrorCode ierr;
5916   char           filename[PETSC_MAX_PATH_LEN];
5917   PetscViewer    viewer;
5918 
5919   PetscFunctionBegin;
5920   if (step < 0) PetscFunctionReturn(0); /* -1 indicates interpolated solution */
5921   ierr = PetscSNPrintf(filename,sizeof(filename),(const char*)filenametemplate,step);CHKERRQ(ierr);
5922   ierr = PetscViewerVTKOpen(PetscObjectComm((PetscObject)ts),filename,FILE_MODE_WRITE,&viewer);CHKERRQ(ierr);
5923   ierr = VecView(u,viewer);CHKERRQ(ierr);
5924   ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr);
5925   PetscFunctionReturn(0);
5926 }
5927 
5928 /*@C
5929    TSMonitorSolutionVTKDestroy - Destroy context for monitoring
5930 
5931    Collective on TS
5932 
5933    Input Parameters:
5934 .  filenametemplate - string containing a format specifier for the integer time step (e.g. %03D)
5935 
5936    Level: intermediate
5937 
5938    Note:
5939    This function is normally passed to TSMonitorSet() along with TSMonitorSolutionVTK().
5940 
5941 .keywords: TS,  vector, monitor, view
5942 
5943 .seealso: TSMonitorSet(), TSMonitorSolutionVTK()
5944 @*/
5945 PetscErrorCode TSMonitorSolutionVTKDestroy(void *filenametemplate)
5946 {
5947   PetscErrorCode ierr;
5948 
5949   PetscFunctionBegin;
5950   ierr = PetscFree(*(char**)filenametemplate);CHKERRQ(ierr);
5951   PetscFunctionReturn(0);
5952 }
5953 
5954 /*@
5955    TSGetAdapt - Get the adaptive controller context for the current method
5956 
5957    Collective on TS if controller has not been created yet
5958 
5959    Input Arguments:
5960 .  ts - time stepping context
5961 
5962    Output Arguments:
5963 .  adapt - adaptive controller
5964 
5965    Level: intermediate
5966 
5967 .seealso: TSAdapt, TSAdaptSetType(), TSAdaptChoose()
5968 @*/
5969 PetscErrorCode TSGetAdapt(TS ts,TSAdapt *adapt)
5970 {
5971   PetscErrorCode ierr;
5972 
5973   PetscFunctionBegin;
5974   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
5975   PetscValidPointer(adapt,2);
5976   if (!ts->adapt) {
5977     ierr = TSAdaptCreate(PetscObjectComm((PetscObject)ts),&ts->adapt);CHKERRQ(ierr);
5978     ierr = PetscLogObjectParent((PetscObject)ts,(PetscObject)ts->adapt);CHKERRQ(ierr);
5979     ierr = PetscObjectIncrementTabLevel((PetscObject)ts->adapt,(PetscObject)ts,1);CHKERRQ(ierr);
5980   }
5981   *adapt = ts->adapt;
5982   PetscFunctionReturn(0);
5983 }
5984 
5985 /*@
5986    TSSetTolerances - Set tolerances for local truncation error when using adaptive controller
5987 
5988    Logically Collective
5989 
5990    Input Arguments:
5991 +  ts - time integration context
5992 .  atol - scalar absolute tolerances, PETSC_DECIDE to leave current value
5993 .  vatol - vector of absolute tolerances or NULL, used in preference to atol if present
5994 .  rtol - scalar relative tolerances, PETSC_DECIDE to leave current value
5995 -  vrtol - vector of relative tolerances or NULL, used in preference to atol if present
5996 
5997    Options Database keys:
5998 +  -ts_rtol <rtol> - relative tolerance for local truncation error
5999 -  -ts_atol <atol> Absolute tolerance for local truncation error
6000 
6001    Notes:
6002    With PETSc's implicit schemes for DAE problems, the calculation of the local truncation error
6003    (LTE) includes both the differential and the algebraic variables. If one wants the LTE to be
6004    computed only for the differential or the algebraic part then this can be done using the vector of
6005    tolerances vatol. For example, by setting the tolerance vector with the desired tolerance for the
6006    differential part and infinity for the algebraic part, the LTE calculation will include only the
6007    differential variables.
6008 
6009    Level: beginner
6010 
6011 .seealso: TS, TSAdapt, TSVecNormWRMS(), TSGetTolerances()
6012 @*/
6013 PetscErrorCode TSSetTolerances(TS ts,PetscReal atol,Vec vatol,PetscReal rtol,Vec vrtol)
6014 {
6015   PetscErrorCode ierr;
6016 
6017   PetscFunctionBegin;
6018   if (atol != PETSC_DECIDE && atol != PETSC_DEFAULT) ts->atol = atol;
6019   if (vatol) {
6020     ierr = PetscObjectReference((PetscObject)vatol);CHKERRQ(ierr);
6021     ierr = VecDestroy(&ts->vatol);CHKERRQ(ierr);
6022     ts->vatol = vatol;
6023   }
6024   if (rtol != PETSC_DECIDE && rtol != PETSC_DEFAULT) ts->rtol = rtol;
6025   if (vrtol) {
6026     ierr = PetscObjectReference((PetscObject)vrtol);CHKERRQ(ierr);
6027     ierr = VecDestroy(&ts->vrtol);CHKERRQ(ierr);
6028     ts->vrtol = vrtol;
6029   }
6030   PetscFunctionReturn(0);
6031 }
6032 
6033 /*@
6034    TSGetTolerances - Get tolerances for local truncation error when using adaptive controller
6035 
6036    Logically Collective
6037 
6038    Input Arguments:
6039 .  ts - time integration context
6040 
6041    Output Arguments:
6042 +  atol - scalar absolute tolerances, NULL to ignore
6043 .  vatol - vector of absolute tolerances, NULL to ignore
6044 .  rtol - scalar relative tolerances, NULL to ignore
6045 -  vrtol - vector of relative tolerances, NULL to ignore
6046 
6047    Level: beginner
6048 
6049 .seealso: TS, TSAdapt, TSVecNormWRMS(), TSSetTolerances()
6050 @*/
6051 PetscErrorCode TSGetTolerances(TS ts,PetscReal *atol,Vec *vatol,PetscReal *rtol,Vec *vrtol)
6052 {
6053   PetscFunctionBegin;
6054   if (atol)  *atol  = ts->atol;
6055   if (vatol) *vatol = ts->vatol;
6056   if (rtol)  *rtol  = ts->rtol;
6057   if (vrtol) *vrtol = ts->vrtol;
6058   PetscFunctionReturn(0);
6059 }
6060 
6061 /*@
6062    TSErrorWeightedNorm2 - compute a weighted 2-norm of the difference between two state vectors
6063 
6064    Collective on TS
6065 
6066    Input Arguments:
6067 +  ts - time stepping context
6068 .  U - state vector, usually ts->vec_sol
6069 -  Y - state vector to be compared to U
6070 
6071    Output Arguments:
6072 .  norm - weighted norm, a value of 1.0 means that the error matches the tolerances
6073 .  norma - weighted norm based on the absolute tolerance, a value of 1.0 means that the error matches the tolerances
6074 .  normr - weighted norm based on the relative tolerance, a value of 1.0 means that the error matches the tolerances
6075 
6076    Level: developer
6077 
6078 .seealso: TSErrorWeightedNorm(), TSErrorWeightedNormInfinity()
6079 @*/
6080 PetscErrorCode TSErrorWeightedNorm2(TS ts,Vec U,Vec Y,PetscReal *norm,PetscReal *norma,PetscReal *normr)
6081 {
6082   PetscErrorCode    ierr;
6083   PetscInt          i,n,N,rstart;
6084   PetscInt          n_loc,na_loc,nr_loc;
6085   PetscReal         n_glb,na_glb,nr_glb;
6086   const PetscScalar *u,*y;
6087   PetscReal         sum,suma,sumr,gsum,gsuma,gsumr,diff;
6088   PetscReal         tol,tola,tolr;
6089   PetscReal         err_loc[6],err_glb[6];
6090 
6091   PetscFunctionBegin;
6092   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
6093   PetscValidHeaderSpecific(U,VEC_CLASSID,2);
6094   PetscValidHeaderSpecific(Y,VEC_CLASSID,3);
6095   PetscValidType(U,2);
6096   PetscValidType(Y,3);
6097   PetscCheckSameComm(U,2,Y,3);
6098   PetscValidPointer(norm,4);
6099   PetscValidPointer(norma,5);
6100   PetscValidPointer(normr,6);
6101   if (U == Y) SETERRQ(PetscObjectComm((PetscObject)U),PETSC_ERR_ARG_IDN,"U and Y cannot be the same vector");
6102 
6103   ierr = VecGetSize(U,&N);CHKERRQ(ierr);
6104   ierr = VecGetLocalSize(U,&n);CHKERRQ(ierr);
6105   ierr = VecGetOwnershipRange(U,&rstart,NULL);CHKERRQ(ierr);
6106   ierr = VecGetArrayRead(U,&u);CHKERRQ(ierr);
6107   ierr = VecGetArrayRead(Y,&y);CHKERRQ(ierr);
6108   sum  = 0.; n_loc  = 0;
6109   suma = 0.; na_loc = 0;
6110   sumr = 0.; nr_loc = 0;
6111   if (ts->vatol && ts->vrtol) {
6112     const PetscScalar *atol,*rtol;
6113     ierr = VecGetArrayRead(ts->vatol,&atol);CHKERRQ(ierr);
6114     ierr = VecGetArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr);
6115     for (i=0; i<n; i++) {
6116       diff = PetscAbsScalar(y[i] - u[i]);
6117       tola = PetscRealPart(atol[i]);
6118       if(tola>0.){
6119         suma  += PetscSqr(diff/tola);
6120         na_loc++;
6121       }
6122       tolr = PetscRealPart(rtol[i]) * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i]));
6123       if(tolr>0.){
6124         sumr  += PetscSqr(diff/tolr);
6125         nr_loc++;
6126       }
6127       tol=tola+tolr;
6128       if(tol>0.){
6129         sum  += PetscSqr(diff/tol);
6130         n_loc++;
6131       }
6132     }
6133     ierr = VecRestoreArrayRead(ts->vatol,&atol);CHKERRQ(ierr);
6134     ierr = VecRestoreArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr);
6135   } else if (ts->vatol) {       /* vector atol, scalar rtol */
6136     const PetscScalar *atol;
6137     ierr = VecGetArrayRead(ts->vatol,&atol);CHKERRQ(ierr);
6138     for (i=0; i<n; i++) {
6139       diff = PetscAbsScalar(y[i] - u[i]);
6140       tola = PetscRealPart(atol[i]);
6141       if(tola>0.){
6142         suma  += PetscSqr(diff/tola);
6143         na_loc++;
6144       }
6145       tolr = ts->rtol * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i]));
6146       if(tolr>0.){
6147         sumr  += PetscSqr(diff/tolr);
6148         nr_loc++;
6149       }
6150       tol=tola+tolr;
6151       if(tol>0.){
6152         sum  += PetscSqr(diff/tol);
6153         n_loc++;
6154       }
6155     }
6156     ierr = VecRestoreArrayRead(ts->vatol,&atol);CHKERRQ(ierr);
6157   } else if (ts->vrtol) {       /* scalar atol, vector rtol */
6158     const PetscScalar *rtol;
6159     ierr = VecGetArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr);
6160     for (i=0; i<n; i++) {
6161       diff = PetscAbsScalar(y[i] - u[i]);
6162       tola = ts->atol;
6163       if(tola>0.){
6164         suma  += PetscSqr(diff/tola);
6165         na_loc++;
6166       }
6167       tolr = PetscRealPart(rtol[i]) * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i]));
6168       if(tolr>0.){
6169         sumr  += PetscSqr(diff/tolr);
6170         nr_loc++;
6171       }
6172       tol=tola+tolr;
6173       if(tol>0.){
6174         sum  += PetscSqr(diff/tol);
6175         n_loc++;
6176       }
6177     }
6178     ierr = VecRestoreArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr);
6179   } else {                      /* scalar atol, scalar rtol */
6180     for (i=0; i<n; i++) {
6181       diff = PetscAbsScalar(y[i] - u[i]);
6182      tola = ts->atol;
6183       if(tola>0.){
6184         suma  += PetscSqr(diff/tola);
6185         na_loc++;
6186       }
6187       tolr = ts->rtol * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i]));
6188       if(tolr>0.){
6189         sumr  += PetscSqr(diff/tolr);
6190         nr_loc++;
6191       }
6192       tol=tola+tolr;
6193       if(tol>0.){
6194         sum  += PetscSqr(diff/tol);
6195         n_loc++;
6196       }
6197     }
6198   }
6199   ierr = VecRestoreArrayRead(U,&u);CHKERRQ(ierr);
6200   ierr = VecRestoreArrayRead(Y,&y);CHKERRQ(ierr);
6201 
6202   err_loc[0] = sum;
6203   err_loc[1] = suma;
6204   err_loc[2] = sumr;
6205   err_loc[3] = (PetscReal)n_loc;
6206   err_loc[4] = (PetscReal)na_loc;
6207   err_loc[5] = (PetscReal)nr_loc;
6208 
6209   ierr = MPIU_Allreduce(err_loc,err_glb,6,MPIU_REAL,MPIU_SUM,PetscObjectComm((PetscObject)ts));CHKERRQ(ierr);
6210 
6211   gsum   = err_glb[0];
6212   gsuma  = err_glb[1];
6213   gsumr  = err_glb[2];
6214   n_glb  = err_glb[3];
6215   na_glb = err_glb[4];
6216   nr_glb = err_glb[5];
6217 
6218   *norm  = 0.;
6219   if(n_glb>0. ){*norm  = PetscSqrtReal(gsum  / n_glb );}
6220   *norma = 0.;
6221   if(na_glb>0.){*norma = PetscSqrtReal(gsuma / na_glb);}
6222   *normr = 0.;
6223   if(nr_glb>0.){*normr = PetscSqrtReal(gsumr / nr_glb);}
6224 
6225   if (PetscIsInfOrNanScalar(*norm)) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_FP,"Infinite or not-a-number generated in norm");
6226   if (PetscIsInfOrNanScalar(*norma)) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_FP,"Infinite or not-a-number generated in norma");
6227   if (PetscIsInfOrNanScalar(*normr)) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_FP,"Infinite or not-a-number generated in normr");
6228   PetscFunctionReturn(0);
6229 }
6230 
6231 /*@
6232    TSErrorWeightedNormInfinity - compute a weighted infinity-norm of the difference between two state vectors
6233 
6234    Collective on TS
6235 
6236    Input Arguments:
6237 +  ts - time stepping context
6238 .  U - state vector, usually ts->vec_sol
6239 -  Y - state vector to be compared to U
6240 
6241    Output Arguments:
6242 .  norm - weighted norm, a value of 1.0 means that the error matches the tolerances
6243 .  norma - weighted norm based on the absolute tolerance, a value of 1.0 means that the error matches the tolerances
6244 .  normr - weighted norm based on the relative tolerance, a value of 1.0 means that the error matches the tolerances
6245 
6246    Level: developer
6247 
6248 .seealso: TSErrorWeightedNorm(), TSErrorWeightedNorm2()
6249 @*/
6250 PetscErrorCode TSErrorWeightedNormInfinity(TS ts,Vec U,Vec Y,PetscReal *norm,PetscReal *norma,PetscReal *normr)
6251 {
6252   PetscErrorCode    ierr;
6253   PetscInt          i,n,N,rstart;
6254   const PetscScalar *u,*y;
6255   PetscReal         max,gmax,maxa,gmaxa,maxr,gmaxr;
6256   PetscReal         tol,tola,tolr,diff;
6257   PetscReal         err_loc[3],err_glb[3];
6258 
6259   PetscFunctionBegin;
6260   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
6261   PetscValidHeaderSpecific(U,VEC_CLASSID,2);
6262   PetscValidHeaderSpecific(Y,VEC_CLASSID,3);
6263   PetscValidType(U,2);
6264   PetscValidType(Y,3);
6265   PetscCheckSameComm(U,2,Y,3);
6266   PetscValidPointer(norm,4);
6267   PetscValidPointer(norma,5);
6268   PetscValidPointer(normr,6);
6269   if (U == Y) SETERRQ(PetscObjectComm((PetscObject)U),PETSC_ERR_ARG_IDN,"U and Y cannot be the same vector");
6270 
6271   ierr = VecGetSize(U,&N);CHKERRQ(ierr);
6272   ierr = VecGetLocalSize(U,&n);CHKERRQ(ierr);
6273   ierr = VecGetOwnershipRange(U,&rstart,NULL);CHKERRQ(ierr);
6274   ierr = VecGetArrayRead(U,&u);CHKERRQ(ierr);
6275   ierr = VecGetArrayRead(Y,&y);CHKERRQ(ierr);
6276 
6277   max=0.;
6278   maxa=0.;
6279   maxr=0.;
6280 
6281   if (ts->vatol && ts->vrtol) {     /* vector atol, vector rtol */
6282     const PetscScalar *atol,*rtol;
6283     ierr = VecGetArrayRead(ts->vatol,&atol);CHKERRQ(ierr);
6284     ierr = VecGetArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr);
6285 
6286     for (i=0; i<n; i++) {
6287       diff = PetscAbsScalar(y[i] - u[i]);
6288       tola = PetscRealPart(atol[i]);
6289       tolr = PetscRealPart(rtol[i]) * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i]));
6290       tol  = tola+tolr;
6291       if(tola>0.){
6292         maxa = PetscMax(maxa,diff / tola);
6293       }
6294       if(tolr>0.){
6295         maxr = PetscMax(maxr,diff / tolr);
6296       }
6297       if(tol>0.){
6298         max = PetscMax(max,diff / tol);
6299       }
6300     }
6301     ierr = VecRestoreArrayRead(ts->vatol,&atol);CHKERRQ(ierr);
6302     ierr = VecRestoreArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr);
6303   } else if (ts->vatol) {       /* vector atol, scalar rtol */
6304     const PetscScalar *atol;
6305     ierr = VecGetArrayRead(ts->vatol,&atol);CHKERRQ(ierr);
6306     for (i=0; i<n; i++) {
6307       diff = PetscAbsScalar(y[i] - u[i]);
6308       tola = PetscRealPart(atol[i]);
6309       tolr = ts->rtol  * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i]));
6310       tol  = tola+tolr;
6311       if(tola>0.){
6312         maxa = PetscMax(maxa,diff / tola);
6313       }
6314       if(tolr>0.){
6315         maxr = PetscMax(maxr,diff / tolr);
6316       }
6317       if(tol>0.){
6318         max = PetscMax(max,diff / tol);
6319       }
6320     }
6321     ierr = VecRestoreArrayRead(ts->vatol,&atol);CHKERRQ(ierr);
6322   } else if (ts->vrtol) {       /* scalar atol, vector rtol */
6323     const PetscScalar *rtol;
6324     ierr = VecGetArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr);
6325 
6326     for (i=0; i<n; i++) {
6327       diff = PetscAbsScalar(y[i] - u[i]);
6328       tola = ts->atol;
6329       tolr = PetscRealPart(rtol[i]) * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i]));
6330       tol  = tola+tolr;
6331       if(tola>0.){
6332         maxa = PetscMax(maxa,diff / tola);
6333       }
6334       if(tolr>0.){
6335         maxr = PetscMax(maxr,diff / tolr);
6336       }
6337       if(tol>0.){
6338         max = PetscMax(max,diff / tol);
6339       }
6340     }
6341     ierr = VecRestoreArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr);
6342   } else {                      /* scalar atol, scalar rtol */
6343 
6344     for (i=0; i<n; i++) {
6345       diff = PetscAbsScalar(y[i] - u[i]);
6346       tola = ts->atol;
6347       tolr = ts->rtol * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i]));
6348       tol  = tola+tolr;
6349       if(tola>0.){
6350         maxa = PetscMax(maxa,diff / tola);
6351       }
6352       if(tolr>0.){
6353         maxr = PetscMax(maxr,diff / tolr);
6354       }
6355       if(tol>0.){
6356         max = PetscMax(max,diff / tol);
6357       }
6358     }
6359   }
6360   ierr = VecRestoreArrayRead(U,&u);CHKERRQ(ierr);
6361   ierr = VecRestoreArrayRead(Y,&y);CHKERRQ(ierr);
6362   err_loc[0] = max;
6363   err_loc[1] = maxa;
6364   err_loc[2] = maxr;
6365   ierr  = MPIU_Allreduce(err_loc,err_glb,3,MPIU_REAL,MPIU_MAX,PetscObjectComm((PetscObject)ts));CHKERRQ(ierr);
6366   gmax   = err_glb[0];
6367   gmaxa  = err_glb[1];
6368   gmaxr  = err_glb[2];
6369 
6370   *norm = gmax;
6371   *norma = gmaxa;
6372   *normr = gmaxr;
6373   if (PetscIsInfOrNanScalar(*norm)) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_FP,"Infinite or not-a-number generated in norm");
6374     if (PetscIsInfOrNanScalar(*norma)) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_FP,"Infinite or not-a-number generated in norma");
6375     if (PetscIsInfOrNanScalar(*normr)) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_FP,"Infinite or not-a-number generated in normr");
6376   PetscFunctionReturn(0);
6377 }
6378 
6379 /*@
6380    TSErrorWeightedNorm - compute a weighted norm of the difference between two state vectors based on supplied absolute and relative tolerances
6381 
6382    Collective on TS
6383 
6384    Input Arguments:
6385 +  ts - time stepping context
6386 .  U - state vector, usually ts->vec_sol
6387 .  Y - state vector to be compared to U
6388 -  wnormtype - norm type, either NORM_2 or NORM_INFINITY
6389 
6390    Output Arguments:
6391 .  norm  - weighted norm, a value of 1.0 achieves a balance between absolute and relative tolerances
6392 .  norma - weighted norm, a value of 1.0 means that the error meets the absolute tolerance set by the user
6393 .  normr - weighted norm, a value of 1.0 means that the error meets the relative tolerance set by the user
6394 
6395    Options Database Keys:
6396 .  -ts_adapt_wnormtype <wnormtype> - 2, INFINITY
6397 
6398    Level: developer
6399 
6400 .seealso: TSErrorWeightedNormInfinity(), TSErrorWeightedNorm2(), TSErrorWeightedENorm
6401 @*/
6402 PetscErrorCode TSErrorWeightedNorm(TS ts,Vec U,Vec Y,NormType wnormtype,PetscReal *norm,PetscReal *norma,PetscReal *normr)
6403 {
6404   PetscErrorCode ierr;
6405 
6406   PetscFunctionBegin;
6407   if (wnormtype == NORM_2) {
6408     ierr = TSErrorWeightedNorm2(ts,U,Y,norm,norma,normr);CHKERRQ(ierr);
6409   } else if(wnormtype == NORM_INFINITY) {
6410     ierr = TSErrorWeightedNormInfinity(ts,U,Y,norm,norma,normr);CHKERRQ(ierr);
6411   } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"No support for norm type %s",NormTypes[wnormtype]);
6412   PetscFunctionReturn(0);
6413 }
6414 
6415 
6416 /*@
6417    TSErrorWeightedENorm2 - compute a weighted 2 error norm based on supplied absolute and relative tolerances
6418 
6419    Collective on TS
6420 
6421    Input Arguments:
6422 +  ts - time stepping context
6423 .  E - error vector
6424 .  U - state vector, usually ts->vec_sol
6425 -  Y - state vector, previous time step
6426 
6427    Output Arguments:
6428 .  norm - weighted norm, a value of 1.0 means that the error matches the tolerances
6429 .  norma - weighted norm based on the absolute tolerance, a value of 1.0 means that the error matches the tolerances
6430 .  normr - weighted norm based on the relative tolerance, a value of 1.0 means that the error matches the tolerances
6431 
6432    Level: developer
6433 
6434 .seealso: TSErrorWeightedENorm(), TSErrorWeightedENormInfinity()
6435 @*/
6436 PetscErrorCode TSErrorWeightedENorm2(TS ts,Vec E,Vec U,Vec Y,PetscReal *norm,PetscReal *norma,PetscReal *normr)
6437 {
6438   PetscErrorCode    ierr;
6439   PetscInt          i,n,N,rstart;
6440   PetscInt          n_loc,na_loc,nr_loc;
6441   PetscReal         n_glb,na_glb,nr_glb;
6442   const PetscScalar *e,*u,*y;
6443   PetscReal         err,sum,suma,sumr,gsum,gsuma,gsumr;
6444   PetscReal         tol,tola,tolr;
6445   PetscReal         err_loc[6],err_glb[6];
6446 
6447   PetscFunctionBegin;
6448   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
6449   PetscValidHeaderSpecific(E,VEC_CLASSID,2);
6450   PetscValidHeaderSpecific(U,VEC_CLASSID,3);
6451   PetscValidHeaderSpecific(Y,VEC_CLASSID,4);
6452   PetscValidType(E,2);
6453   PetscValidType(U,3);
6454   PetscValidType(Y,4);
6455   PetscCheckSameComm(E,2,U,3);
6456   PetscCheckSameComm(U,2,Y,3);
6457   PetscValidPointer(norm,5);
6458   PetscValidPointer(norma,6);
6459   PetscValidPointer(normr,7);
6460 
6461   ierr = VecGetSize(E,&N);CHKERRQ(ierr);
6462   ierr = VecGetLocalSize(E,&n);CHKERRQ(ierr);
6463   ierr = VecGetOwnershipRange(E,&rstart,NULL);CHKERRQ(ierr);
6464   ierr = VecGetArrayRead(E,&e);CHKERRQ(ierr);
6465   ierr = VecGetArrayRead(U,&u);CHKERRQ(ierr);
6466   ierr = VecGetArrayRead(Y,&y);CHKERRQ(ierr);
6467   sum  = 0.; n_loc  = 0;
6468   suma = 0.; na_loc = 0;
6469   sumr = 0.; nr_loc = 0;
6470   if (ts->vatol && ts->vrtol) {
6471     const PetscScalar *atol,*rtol;
6472     ierr = VecGetArrayRead(ts->vatol,&atol);CHKERRQ(ierr);
6473     ierr = VecGetArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr);
6474     for (i=0; i<n; i++) {
6475       err = PetscAbsScalar(e[i]);
6476       tola = PetscRealPart(atol[i]);
6477       if(tola>0.){
6478         suma  += PetscSqr(err/tola);
6479         na_loc++;
6480       }
6481       tolr = PetscRealPart(rtol[i]) * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i]));
6482       if(tolr>0.){
6483         sumr  += PetscSqr(err/tolr);
6484         nr_loc++;
6485       }
6486       tol=tola+tolr;
6487       if(tol>0.){
6488         sum  += PetscSqr(err/tol);
6489         n_loc++;
6490       }
6491     }
6492     ierr = VecRestoreArrayRead(ts->vatol,&atol);CHKERRQ(ierr);
6493     ierr = VecRestoreArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr);
6494   } else if (ts->vatol) {       /* vector atol, scalar rtol */
6495     const PetscScalar *atol;
6496     ierr = VecGetArrayRead(ts->vatol,&atol);CHKERRQ(ierr);
6497     for (i=0; i<n; i++) {
6498       err = PetscAbsScalar(e[i]);
6499       tola = PetscRealPart(atol[i]);
6500       if(tola>0.){
6501         suma  += PetscSqr(err/tola);
6502         na_loc++;
6503       }
6504       tolr = ts->rtol * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i]));
6505       if(tolr>0.){
6506         sumr  += PetscSqr(err/tolr);
6507         nr_loc++;
6508       }
6509       tol=tola+tolr;
6510       if(tol>0.){
6511         sum  += PetscSqr(err/tol);
6512         n_loc++;
6513       }
6514     }
6515     ierr = VecRestoreArrayRead(ts->vatol,&atol);CHKERRQ(ierr);
6516   } else if (ts->vrtol) {       /* scalar atol, vector rtol */
6517     const PetscScalar *rtol;
6518     ierr = VecGetArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr);
6519     for (i=0; i<n; i++) {
6520       err = PetscAbsScalar(e[i]);
6521       tola = ts->atol;
6522       if(tola>0.){
6523         suma  += PetscSqr(err/tola);
6524         na_loc++;
6525       }
6526       tolr = PetscRealPart(rtol[i]) * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i]));
6527       if(tolr>0.){
6528         sumr  += PetscSqr(err/tolr);
6529         nr_loc++;
6530       }
6531       tol=tola+tolr;
6532       if(tol>0.){
6533         sum  += PetscSqr(err/tol);
6534         n_loc++;
6535       }
6536     }
6537     ierr = VecRestoreArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr);
6538   } else {                      /* scalar atol, scalar rtol */
6539     for (i=0; i<n; i++) {
6540       err = PetscAbsScalar(e[i]);
6541      tola = ts->atol;
6542       if(tola>0.){
6543         suma  += PetscSqr(err/tola);
6544         na_loc++;
6545       }
6546       tolr = ts->rtol * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i]));
6547       if(tolr>0.){
6548         sumr  += PetscSqr(err/tolr);
6549         nr_loc++;
6550       }
6551       tol=tola+tolr;
6552       if(tol>0.){
6553         sum  += PetscSqr(err/tol);
6554         n_loc++;
6555       }
6556     }
6557   }
6558   ierr = VecRestoreArrayRead(E,&e);CHKERRQ(ierr);
6559   ierr = VecRestoreArrayRead(U,&u);CHKERRQ(ierr);
6560   ierr = VecRestoreArrayRead(Y,&y);CHKERRQ(ierr);
6561 
6562   err_loc[0] = sum;
6563   err_loc[1] = suma;
6564   err_loc[2] = sumr;
6565   err_loc[3] = (PetscReal)n_loc;
6566   err_loc[4] = (PetscReal)na_loc;
6567   err_loc[5] = (PetscReal)nr_loc;
6568 
6569   ierr = MPIU_Allreduce(err_loc,err_glb,6,MPIU_REAL,MPIU_SUM,PetscObjectComm((PetscObject)ts));CHKERRQ(ierr);
6570 
6571   gsum   = err_glb[0];
6572   gsuma  = err_glb[1];
6573   gsumr  = err_glb[2];
6574   n_glb  = err_glb[3];
6575   na_glb = err_glb[4];
6576   nr_glb = err_glb[5];
6577 
6578   *norm  = 0.;
6579   if(n_glb>0. ){*norm  = PetscSqrtReal(gsum  / n_glb );}
6580   *norma = 0.;
6581   if(na_glb>0.){*norma = PetscSqrtReal(gsuma / na_glb);}
6582   *normr = 0.;
6583   if(nr_glb>0.){*normr = PetscSqrtReal(gsumr / nr_glb);}
6584 
6585   if (PetscIsInfOrNanScalar(*norm)) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_FP,"Infinite or not-a-number generated in norm");
6586   if (PetscIsInfOrNanScalar(*norma)) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_FP,"Infinite or not-a-number generated in norma");
6587   if (PetscIsInfOrNanScalar(*normr)) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_FP,"Infinite or not-a-number generated in normr");
6588   PetscFunctionReturn(0);
6589 }
6590 
6591 /*@
6592    TSErrorWeightedENormInfinity - compute a weighted infinity error norm based on supplied absolute and relative tolerances
6593    Collective on TS
6594 
6595    Input Arguments:
6596 +  ts - time stepping context
6597 .  E - error vector
6598 .  U - state vector, usually ts->vec_sol
6599 -  Y - state vector, previous time step
6600 
6601    Output Arguments:
6602 .  norm - weighted norm, a value of 1.0 means that the error matches the tolerances
6603 .  norma - weighted norm based on the absolute tolerance, a value of 1.0 means that the error matches the tolerances
6604 .  normr - weighted norm based on the relative tolerance, a value of 1.0 means that the error matches the tolerances
6605 
6606    Level: developer
6607 
6608 .seealso: TSErrorWeightedENorm(), TSErrorWeightedENorm2()
6609 @*/
6610 PetscErrorCode TSErrorWeightedENormInfinity(TS ts,Vec E,Vec U,Vec Y,PetscReal *norm,PetscReal *norma,PetscReal *normr)
6611 {
6612   PetscErrorCode    ierr;
6613   PetscInt          i,n,N,rstart;
6614   const PetscScalar *e,*u,*y;
6615   PetscReal         err,max,gmax,maxa,gmaxa,maxr,gmaxr;
6616   PetscReal         tol,tola,tolr;
6617   PetscReal         err_loc[3],err_glb[3];
6618 
6619   PetscFunctionBegin;
6620   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
6621   PetscValidHeaderSpecific(E,VEC_CLASSID,2);
6622   PetscValidHeaderSpecific(U,VEC_CLASSID,3);
6623   PetscValidHeaderSpecific(Y,VEC_CLASSID,4);
6624   PetscValidType(E,2);
6625   PetscValidType(U,3);
6626   PetscValidType(Y,4);
6627   PetscCheckSameComm(E,2,U,3);
6628   PetscCheckSameComm(U,2,Y,3);
6629   PetscValidPointer(norm,5);
6630   PetscValidPointer(norma,6);
6631   PetscValidPointer(normr,7);
6632 
6633   ierr = VecGetSize(E,&N);CHKERRQ(ierr);
6634   ierr = VecGetLocalSize(E,&n);CHKERRQ(ierr);
6635   ierr = VecGetOwnershipRange(E,&rstart,NULL);CHKERRQ(ierr);
6636   ierr = VecGetArrayRead(E,&e);CHKERRQ(ierr);
6637   ierr = VecGetArrayRead(U,&u);CHKERRQ(ierr);
6638   ierr = VecGetArrayRead(Y,&y);CHKERRQ(ierr);
6639 
6640   max=0.;
6641   maxa=0.;
6642   maxr=0.;
6643 
6644   if (ts->vatol && ts->vrtol) {     /* vector atol, vector rtol */
6645     const PetscScalar *atol,*rtol;
6646     ierr = VecGetArrayRead(ts->vatol,&atol);CHKERRQ(ierr);
6647     ierr = VecGetArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr);
6648 
6649     for (i=0; i<n; i++) {
6650       err = PetscAbsScalar(e[i]);
6651       tola = PetscRealPart(atol[i]);
6652       tolr = PetscRealPart(rtol[i]) * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i]));
6653       tol  = tola+tolr;
6654       if(tola>0.){
6655         maxa = PetscMax(maxa,err / tola);
6656       }
6657       if(tolr>0.){
6658         maxr = PetscMax(maxr,err / tolr);
6659       }
6660       if(tol>0.){
6661         max = PetscMax(max,err / tol);
6662       }
6663     }
6664     ierr = VecRestoreArrayRead(ts->vatol,&atol);CHKERRQ(ierr);
6665     ierr = VecRestoreArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr);
6666   } else if (ts->vatol) {       /* vector atol, scalar rtol */
6667     const PetscScalar *atol;
6668     ierr = VecGetArrayRead(ts->vatol,&atol);CHKERRQ(ierr);
6669     for (i=0; i<n; i++) {
6670       err = PetscAbsScalar(e[i]);
6671       tola = PetscRealPart(atol[i]);
6672       tolr = ts->rtol  * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i]));
6673       tol  = tola+tolr;
6674       if(tola>0.){
6675         maxa = PetscMax(maxa,err / tola);
6676       }
6677       if(tolr>0.){
6678         maxr = PetscMax(maxr,err / tolr);
6679       }
6680       if(tol>0.){
6681         max = PetscMax(max,err / tol);
6682       }
6683     }
6684     ierr = VecRestoreArrayRead(ts->vatol,&atol);CHKERRQ(ierr);
6685   } else if (ts->vrtol) {       /* scalar atol, vector rtol */
6686     const PetscScalar *rtol;
6687     ierr = VecGetArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr);
6688 
6689     for (i=0; i<n; i++) {
6690       err = PetscAbsScalar(e[i]);
6691       tola = ts->atol;
6692       tolr = PetscRealPart(rtol[i]) * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i]));
6693       tol  = tola+tolr;
6694       if(tola>0.){
6695         maxa = PetscMax(maxa,err / tola);
6696       }
6697       if(tolr>0.){
6698         maxr = PetscMax(maxr,err / tolr);
6699       }
6700       if(tol>0.){
6701         max = PetscMax(max,err / tol);
6702       }
6703     }
6704     ierr = VecRestoreArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr);
6705   } else {                      /* scalar atol, scalar rtol */
6706 
6707     for (i=0; i<n; i++) {
6708       err = PetscAbsScalar(e[i]);
6709       tola = ts->atol;
6710       tolr = ts->rtol * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i]));
6711       tol  = tola+tolr;
6712       if(tola>0.){
6713         maxa = PetscMax(maxa,err / tola);
6714       }
6715       if(tolr>0.){
6716         maxr = PetscMax(maxr,err / tolr);
6717       }
6718       if(tol>0.){
6719         max = PetscMax(max,err / tol);
6720       }
6721     }
6722   }
6723   ierr = VecRestoreArrayRead(E,&e);CHKERRQ(ierr);
6724   ierr = VecRestoreArrayRead(U,&u);CHKERRQ(ierr);
6725   ierr = VecRestoreArrayRead(Y,&y);CHKERRQ(ierr);
6726   err_loc[0] = max;
6727   err_loc[1] = maxa;
6728   err_loc[2] = maxr;
6729   ierr  = MPIU_Allreduce(err_loc,err_glb,3,MPIU_REAL,MPIU_MAX,PetscObjectComm((PetscObject)ts));CHKERRQ(ierr);
6730   gmax   = err_glb[0];
6731   gmaxa  = err_glb[1];
6732   gmaxr  = err_glb[2];
6733 
6734   *norm = gmax;
6735   *norma = gmaxa;
6736   *normr = gmaxr;
6737   if (PetscIsInfOrNanScalar(*norm)) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_FP,"Infinite or not-a-number generated in norm");
6738     if (PetscIsInfOrNanScalar(*norma)) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_FP,"Infinite or not-a-number generated in norma");
6739     if (PetscIsInfOrNanScalar(*normr)) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_FP,"Infinite or not-a-number generated in normr");
6740   PetscFunctionReturn(0);
6741 }
6742 
6743 /*@
6744    TSErrorWeightedENorm - compute a weighted error norm based on supplied absolute and relative tolerances
6745 
6746    Collective on TS
6747 
6748    Input Arguments:
6749 +  ts - time stepping context
6750 .  E - error vector
6751 .  U - state vector, usually ts->vec_sol
6752 .  Y - state vector, previous time step
6753 -  wnormtype - norm type, either NORM_2 or NORM_INFINITY
6754 
6755    Output Arguments:
6756 .  norm  - weighted norm, a value of 1.0 achieves a balance between absolute and relative tolerances
6757 .  norma - weighted norm, a value of 1.0 means that the error meets the absolute tolerance set by the user
6758 .  normr - weighted norm, a value of 1.0 means that the error meets the relative tolerance set by the user
6759 
6760    Options Database Keys:
6761 .  -ts_adapt_wnormtype <wnormtype> - 2, INFINITY
6762 
6763    Level: developer
6764 
6765 .seealso: TSErrorWeightedENormInfinity(), TSErrorWeightedENorm2(), TSErrorWeightedNormInfinity(), TSErrorWeightedNorm2()
6766 @*/
6767 PetscErrorCode TSErrorWeightedENorm(TS ts,Vec E,Vec U,Vec Y,NormType wnormtype,PetscReal *norm,PetscReal *norma,PetscReal *normr)
6768 {
6769   PetscErrorCode ierr;
6770 
6771   PetscFunctionBegin;
6772   if (wnormtype == NORM_2) {
6773     ierr = TSErrorWeightedENorm2(ts,E,U,Y,norm,norma,normr);CHKERRQ(ierr);
6774   } else if(wnormtype == NORM_INFINITY) {
6775     ierr = TSErrorWeightedENormInfinity(ts,E,U,Y,norm,norma,normr);CHKERRQ(ierr);
6776   } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"No support for norm type %s",NormTypes[wnormtype]);
6777   PetscFunctionReturn(0);
6778 }
6779 
6780 
6781 /*@
6782    TSSetCFLTimeLocal - Set the local CFL constraint relative to forward Euler
6783 
6784    Logically Collective on TS
6785 
6786    Input Arguments:
6787 +  ts - time stepping context
6788 -  cfltime - maximum stable time step if using forward Euler (value can be different on each process)
6789 
6790    Note:
6791    After calling this function, the global CFL time can be obtained by calling TSGetCFLTime()
6792 
6793    Level: intermediate
6794 
6795 .seealso: TSGetCFLTime(), TSADAPTCFL
6796 @*/
6797 PetscErrorCode TSSetCFLTimeLocal(TS ts,PetscReal cfltime)
6798 {
6799   PetscFunctionBegin;
6800   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
6801   ts->cfltime_local = cfltime;
6802   ts->cfltime       = -1.;
6803   PetscFunctionReturn(0);
6804 }
6805 
6806 /*@
6807    TSGetCFLTime - Get the maximum stable time step according to CFL criteria applied to forward Euler
6808 
6809    Collective on TS
6810 
6811    Input Arguments:
6812 .  ts - time stepping context
6813 
6814    Output Arguments:
6815 .  cfltime - maximum stable time step for forward Euler
6816 
6817    Level: advanced
6818 
6819 .seealso: TSSetCFLTimeLocal()
6820 @*/
6821 PetscErrorCode TSGetCFLTime(TS ts,PetscReal *cfltime)
6822 {
6823   PetscErrorCode ierr;
6824 
6825   PetscFunctionBegin;
6826   if (ts->cfltime < 0) {
6827     ierr = MPIU_Allreduce(&ts->cfltime_local,&ts->cfltime,1,MPIU_REAL,MPIU_MIN,PetscObjectComm((PetscObject)ts));CHKERRQ(ierr);
6828   }
6829   *cfltime = ts->cfltime;
6830   PetscFunctionReturn(0);
6831 }
6832 
6833 /*@
6834    TSVISetVariableBounds - Sets the lower and upper bounds for the solution vector. xl <= x <= xu
6835 
6836    Input Parameters:
6837 .  ts   - the TS context.
6838 .  xl   - lower bound.
6839 .  xu   - upper bound.
6840 
6841    Notes:
6842    If this routine is not called then the lower and upper bounds are set to
6843    PETSC_NINFINITY and PETSC_INFINITY respectively during SNESSetUp().
6844 
6845    Level: advanced
6846 
6847 @*/
6848 PetscErrorCode TSVISetVariableBounds(TS ts, Vec xl, Vec xu)
6849 {
6850   PetscErrorCode ierr;
6851   SNES           snes;
6852 
6853   PetscFunctionBegin;
6854   ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr);
6855   ierr = SNESVISetVariableBounds(snes,xl,xu);CHKERRQ(ierr);
6856   PetscFunctionReturn(0);
6857 }
6858 
6859 #if defined(PETSC_HAVE_MATLAB_ENGINE)
6860 #include <mex.h>
6861 
6862 typedef struct {char *funcname; mxArray *ctx;} TSMatlabContext;
6863 
6864 /*
6865    TSComputeFunction_Matlab - Calls the function that has been set with
6866                          TSSetFunctionMatlab().
6867 
6868    Collective on TS
6869 
6870    Input Parameters:
6871 +  snes - the TS context
6872 -  u - input vector
6873 
6874    Output Parameter:
6875 .  y - function vector, as set by TSSetFunction()
6876 
6877    Notes:
6878    TSComputeFunction() is typically used within nonlinear solvers
6879    implementations, so most users would not generally call this routine
6880    themselves.
6881 
6882    Level: developer
6883 
6884 .keywords: TS, nonlinear, compute, function
6885 
6886 .seealso: TSSetFunction(), TSGetFunction()
6887 */
6888 PetscErrorCode  TSComputeFunction_Matlab(TS snes,PetscReal time,Vec u,Vec udot,Vec y, void *ctx)
6889 {
6890   PetscErrorCode  ierr;
6891   TSMatlabContext *sctx = (TSMatlabContext*)ctx;
6892   int             nlhs  = 1,nrhs = 7;
6893   mxArray         *plhs[1],*prhs[7];
6894   long long int   lx = 0,lxdot = 0,ly = 0,ls = 0;
6895 
6896   PetscFunctionBegin;
6897   PetscValidHeaderSpecific(snes,TS_CLASSID,1);
6898   PetscValidHeaderSpecific(u,VEC_CLASSID,3);
6899   PetscValidHeaderSpecific(udot,VEC_CLASSID,4);
6900   PetscValidHeaderSpecific(y,VEC_CLASSID,5);
6901   PetscCheckSameComm(snes,1,u,3);
6902   PetscCheckSameComm(snes,1,y,5);
6903 
6904   ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr);
6905   ierr = PetscMemcpy(&lx,&u,sizeof(u));CHKERRQ(ierr);
6906   ierr = PetscMemcpy(&lxdot,&udot,sizeof(udot));CHKERRQ(ierr);
6907   ierr = PetscMemcpy(&ly,&y,sizeof(u));CHKERRQ(ierr);
6908 
6909   prhs[0] =  mxCreateDoubleScalar((double)ls);
6910   prhs[1] =  mxCreateDoubleScalar(time);
6911   prhs[2] =  mxCreateDoubleScalar((double)lx);
6912   prhs[3] =  mxCreateDoubleScalar((double)lxdot);
6913   prhs[4] =  mxCreateDoubleScalar((double)ly);
6914   prhs[5] =  mxCreateString(sctx->funcname);
6915   prhs[6] =  sctx->ctx;
6916   ierr    =  mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscTSComputeFunctionInternal");CHKERRQ(ierr);
6917   ierr    =  mxGetScalar(plhs[0]);CHKERRQ(ierr);
6918   mxDestroyArray(prhs[0]);
6919   mxDestroyArray(prhs[1]);
6920   mxDestroyArray(prhs[2]);
6921   mxDestroyArray(prhs[3]);
6922   mxDestroyArray(prhs[4]);
6923   mxDestroyArray(prhs[5]);
6924   mxDestroyArray(plhs[0]);
6925   PetscFunctionReturn(0);
6926 }
6927 
6928 /*
6929    TSSetFunctionMatlab - Sets the function evaluation routine and function
6930    vector for use by the TS routines in solving ODEs
6931    equations from MATLAB. Here the function is a string containing the name of a MATLAB function
6932 
6933    Logically Collective on TS
6934 
6935    Input Parameters:
6936 +  ts - the TS context
6937 -  func - function evaluation routine
6938 
6939    Calling sequence of func:
6940 $    func (TS ts,PetscReal time,Vec u,Vec udot,Vec f,void *ctx);
6941 
6942    Level: beginner
6943 
6944 .keywords: TS, nonlinear, set, function
6945 
6946 .seealso: TSGetFunction(), TSComputeFunction(), TSSetJacobian(), TSSetFunction()
6947 */
6948 PetscErrorCode  TSSetFunctionMatlab(TS ts,const char *func,mxArray *ctx)
6949 {
6950   PetscErrorCode  ierr;
6951   TSMatlabContext *sctx;
6952 
6953   PetscFunctionBegin;
6954   /* currently sctx is memory bleed */
6955   ierr = PetscNew(&sctx);CHKERRQ(ierr);
6956   ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr);
6957   /*
6958      This should work, but it doesn't
6959   sctx->ctx = ctx;
6960   mexMakeArrayPersistent(sctx->ctx);
6961   */
6962   sctx->ctx = mxDuplicateArray(ctx);
6963 
6964   ierr = TSSetIFunction(ts,NULL,TSComputeFunction_Matlab,sctx);CHKERRQ(ierr);
6965   PetscFunctionReturn(0);
6966 }
6967 
6968 /*
6969    TSComputeJacobian_Matlab - Calls the function that has been set with
6970                          TSSetJacobianMatlab().
6971 
6972    Collective on TS
6973 
6974    Input Parameters:
6975 +  ts - the TS context
6976 .  u - input vector
6977 .  A, B - the matrices
6978 -  ctx - user context
6979 
6980    Level: developer
6981 
6982 .keywords: TS, nonlinear, compute, function
6983 
6984 .seealso: TSSetFunction(), TSGetFunction()
6985 @*/
6986 PetscErrorCode  TSComputeJacobian_Matlab(TS ts,PetscReal time,Vec u,Vec udot,PetscReal shift,Mat A,Mat B,void *ctx)
6987 {
6988   PetscErrorCode  ierr;
6989   TSMatlabContext *sctx = (TSMatlabContext*)ctx;
6990   int             nlhs  = 2,nrhs = 9;
6991   mxArray         *plhs[2],*prhs[9];
6992   long long int   lx = 0,lxdot = 0,lA = 0,ls = 0, lB = 0;
6993 
6994   PetscFunctionBegin;
6995   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
6996   PetscValidHeaderSpecific(u,VEC_CLASSID,3);
6997 
6998   /* call Matlab function in ctx with arguments u and y */
6999 
7000   ierr = PetscMemcpy(&ls,&ts,sizeof(ts));CHKERRQ(ierr);
7001   ierr = PetscMemcpy(&lx,&u,sizeof(u));CHKERRQ(ierr);
7002   ierr = PetscMemcpy(&lxdot,&udot,sizeof(u));CHKERRQ(ierr);
7003   ierr = PetscMemcpy(&lA,A,sizeof(u));CHKERRQ(ierr);
7004   ierr = PetscMemcpy(&lB,B,sizeof(u));CHKERRQ(ierr);
7005 
7006   prhs[0] =  mxCreateDoubleScalar((double)ls);
7007   prhs[1] =  mxCreateDoubleScalar((double)time);
7008   prhs[2] =  mxCreateDoubleScalar((double)lx);
7009   prhs[3] =  mxCreateDoubleScalar((double)lxdot);
7010   prhs[4] =  mxCreateDoubleScalar((double)shift);
7011   prhs[5] =  mxCreateDoubleScalar((double)lA);
7012   prhs[6] =  mxCreateDoubleScalar((double)lB);
7013   prhs[7] =  mxCreateString(sctx->funcname);
7014   prhs[8] =  sctx->ctx;
7015   ierr    =  mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscTSComputeJacobianInternal");CHKERRQ(ierr);
7016   ierr    =  mxGetScalar(plhs[0]);CHKERRQ(ierr);
7017   mxDestroyArray(prhs[0]);
7018   mxDestroyArray(prhs[1]);
7019   mxDestroyArray(prhs[2]);
7020   mxDestroyArray(prhs[3]);
7021   mxDestroyArray(prhs[4]);
7022   mxDestroyArray(prhs[5]);
7023   mxDestroyArray(prhs[6]);
7024   mxDestroyArray(prhs[7]);
7025   mxDestroyArray(plhs[0]);
7026   mxDestroyArray(plhs[1]);
7027   PetscFunctionReturn(0);
7028 }
7029 
7030 /*
7031    TSSetJacobianMatlab - Sets the Jacobian function evaluation routine and two empty Jacobian matrices
7032    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
7033 
7034    Logically Collective on TS
7035 
7036    Input Parameters:
7037 +  ts - the TS context
7038 .  A,B - Jacobian matrices
7039 .  func - function evaluation routine
7040 -  ctx - user context
7041 
7042    Calling sequence of func:
7043 $    flag = func (TS ts,PetscReal time,Vec u,Vec udot,Mat A,Mat B,void *ctx);
7044 
7045    Level: developer
7046 
7047 .keywords: TS, nonlinear, set, function
7048 
7049 .seealso: TSGetFunction(), TSComputeFunction(), TSSetJacobian(), TSSetFunction()
7050 */
7051 PetscErrorCode  TSSetJacobianMatlab(TS ts,Mat A,Mat B,const char *func,mxArray *ctx)
7052 {
7053   PetscErrorCode  ierr;
7054   TSMatlabContext *sctx;
7055 
7056   PetscFunctionBegin;
7057   /* currently sctx is memory bleed */
7058   ierr = PetscNew(&sctx);CHKERRQ(ierr);
7059   ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr);
7060   /*
7061      This should work, but it doesn't
7062   sctx->ctx = ctx;
7063   mexMakeArrayPersistent(sctx->ctx);
7064   */
7065   sctx->ctx = mxDuplicateArray(ctx);
7066 
7067   ierr = TSSetIJacobian(ts,A,B,TSComputeJacobian_Matlab,sctx);CHKERRQ(ierr);
7068   PetscFunctionReturn(0);
7069 }
7070 
7071 /*
7072    TSMonitor_Matlab - Calls the function that has been set with TSMonitorSetMatlab().
7073 
7074    Collective on TS
7075 
7076 .seealso: TSSetFunction(), TSGetFunction()
7077 @*/
7078 PetscErrorCode  TSMonitor_Matlab(TS ts,PetscInt it, PetscReal time,Vec u, void *ctx)
7079 {
7080   PetscErrorCode  ierr;
7081   TSMatlabContext *sctx = (TSMatlabContext*)ctx;
7082   int             nlhs  = 1,nrhs = 6;
7083   mxArray         *plhs[1],*prhs[6];
7084   long long int   lx = 0,ls = 0;
7085 
7086   PetscFunctionBegin;
7087   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
7088   PetscValidHeaderSpecific(u,VEC_CLASSID,4);
7089 
7090   ierr = PetscMemcpy(&ls,&ts,sizeof(ts));CHKERRQ(ierr);
7091   ierr = PetscMemcpy(&lx,&u,sizeof(u));CHKERRQ(ierr);
7092 
7093   prhs[0] =  mxCreateDoubleScalar((double)ls);
7094   prhs[1] =  mxCreateDoubleScalar((double)it);
7095   prhs[2] =  mxCreateDoubleScalar((double)time);
7096   prhs[3] =  mxCreateDoubleScalar((double)lx);
7097   prhs[4] =  mxCreateString(sctx->funcname);
7098   prhs[5] =  sctx->ctx;
7099   ierr    =  mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscTSMonitorInternal");CHKERRQ(ierr);
7100   ierr    =  mxGetScalar(plhs[0]);CHKERRQ(ierr);
7101   mxDestroyArray(prhs[0]);
7102   mxDestroyArray(prhs[1]);
7103   mxDestroyArray(prhs[2]);
7104   mxDestroyArray(prhs[3]);
7105   mxDestroyArray(prhs[4]);
7106   mxDestroyArray(plhs[0]);
7107   PetscFunctionReturn(0);
7108 }
7109 
7110 /*
7111    TSMonitorSetMatlab - Sets the monitor function from Matlab
7112 
7113    Level: developer
7114 
7115 .keywords: TS, nonlinear, set, function
7116 
7117 .seealso: TSGetFunction(), TSComputeFunction(), TSSetJacobian(), TSSetFunction()
7118 */
7119 PetscErrorCode  TSMonitorSetMatlab(TS ts,const char *func,mxArray *ctx)
7120 {
7121   PetscErrorCode  ierr;
7122   TSMatlabContext *sctx;
7123 
7124   PetscFunctionBegin;
7125   /* currently sctx is memory bleed */
7126   ierr = PetscNew(&sctx);CHKERRQ(ierr);
7127   ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr);
7128   /*
7129      This should work, but it doesn't
7130   sctx->ctx = ctx;
7131   mexMakeArrayPersistent(sctx->ctx);
7132   */
7133   sctx->ctx = mxDuplicateArray(ctx);
7134 
7135   ierr = TSMonitorSet(ts,TSMonitor_Matlab,sctx,NULL);CHKERRQ(ierr);
7136   PetscFunctionReturn(0);
7137 }
7138 #endif
7139 
7140 /*@C
7141    TSMonitorLGSolution - Monitors progress of the TS solvers by plotting each component of the solution vector
7142        in a time based line graph
7143 
7144    Collective on TS
7145 
7146    Input Parameters:
7147 +  ts - the TS context
7148 .  step - current time-step
7149 .  ptime - current time
7150 .  u - current solution
7151 -  dctx - the TSMonitorLGCtx object that contains all the options for the monitoring, this is created with TSMonitorLGCtxCreate()
7152 
7153    Options Database:
7154 .   -ts_monitor_lg_solution_variables
7155 
7156    Level: intermediate
7157 
7158    Notes: Each process in a parallel run displays its component solutions in a separate window
7159 
7160 .keywords: TS,  vector, monitor, view
7161 
7162 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorLGCtxCreate(), TSMonitorLGCtxSetVariableNames(), TSMonitorLGCtxGetVariableNames(),
7163            TSMonitorLGSetVariableNames(), TSMonitorLGGetVariableNames(), TSMonitorLGSetDisplayVariables(), TSMonitorLGCtxSetDisplayVariables(),
7164            TSMonitorLGCtxSetTransform(), TSMonitorLGSetTransform(), TSMonitorLGError(), TSMonitorLGSNESIterations(), TSMonitorLGKSPIterations(),
7165            TSMonitorEnvelopeCtxCreate(), TSMonitorEnvelopeGetBounds(), TSMonitorEnvelopeCtxDestroy(), TSMonitorEnvelop()
7166 @*/
7167 PetscErrorCode  TSMonitorLGSolution(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dctx)
7168 {
7169   PetscErrorCode    ierr;
7170   TSMonitorLGCtx    ctx = (TSMonitorLGCtx)dctx;
7171   const PetscScalar *yy;
7172   Vec               v;
7173 
7174   PetscFunctionBegin;
7175   if (step < 0) PetscFunctionReturn(0); /* -1 indicates interpolated solution */
7176   if (!step) {
7177     PetscDrawAxis axis;
7178     PetscInt      dim;
7179     ierr = PetscDrawLGGetAxis(ctx->lg,&axis);CHKERRQ(ierr);
7180     ierr = PetscDrawAxisSetLabels(axis,"Solution as function of time","Time","Solution");CHKERRQ(ierr);
7181     if (!ctx->names) {
7182       PetscBool flg;
7183       /* user provides names of variables to plot but no names has been set so assume names are integer values */
7184       ierr = PetscOptionsHasName(((PetscObject)ts)->options,((PetscObject)ts)->prefix,"-ts_monitor_lg_solution_variables",&flg);CHKERRQ(ierr);
7185       if (flg) {
7186         PetscInt i,n;
7187         char     **names;
7188         ierr = VecGetSize(u,&n);CHKERRQ(ierr);
7189         ierr = PetscMalloc1(n+1,&names);CHKERRQ(ierr);
7190         for (i=0; i<n; i++) {
7191           ierr = PetscMalloc1(5,&names[i]);CHKERRQ(ierr);
7192           ierr = PetscSNPrintf(names[i],5,"%D",i);CHKERRQ(ierr);
7193         }
7194         names[n] = NULL;
7195         ctx->names = names;
7196       }
7197     }
7198     if (ctx->names && !ctx->displaynames) {
7199       char      **displaynames;
7200       PetscBool flg;
7201       ierr = VecGetLocalSize(u,&dim);CHKERRQ(ierr);
7202       ierr = PetscMalloc1(dim+1,&displaynames);CHKERRQ(ierr);
7203       ierr = PetscMemzero(displaynames,(dim+1)*sizeof(char*));CHKERRQ(ierr);
7204       ierr = PetscOptionsGetStringArray(((PetscObject)ts)->options,((PetscObject)ts)->prefix,"-ts_monitor_lg_solution_variables",displaynames,&dim,&flg);CHKERRQ(ierr);
7205       if (flg) {
7206         ierr = TSMonitorLGCtxSetDisplayVariables(ctx,(const char *const *)displaynames);CHKERRQ(ierr);
7207       }
7208       ierr = PetscStrArrayDestroy(&displaynames);CHKERRQ(ierr);
7209     }
7210     if (ctx->displaynames) {
7211       ierr = PetscDrawLGSetDimension(ctx->lg,ctx->ndisplayvariables);CHKERRQ(ierr);
7212       ierr = PetscDrawLGSetLegend(ctx->lg,(const char *const *)ctx->displaynames);CHKERRQ(ierr);
7213     } else if (ctx->names) {
7214       ierr = VecGetLocalSize(u,&dim);CHKERRQ(ierr);
7215       ierr = PetscDrawLGSetDimension(ctx->lg,dim);CHKERRQ(ierr);
7216       ierr = PetscDrawLGSetLegend(ctx->lg,(const char *const *)ctx->names);CHKERRQ(ierr);
7217     } else {
7218       ierr = VecGetLocalSize(u,&dim);CHKERRQ(ierr);
7219       ierr = PetscDrawLGSetDimension(ctx->lg,dim);CHKERRQ(ierr);
7220     }
7221     ierr = PetscDrawLGReset(ctx->lg);CHKERRQ(ierr);
7222   }
7223 
7224   if (!ctx->transform) v = u;
7225   else {ierr = (*ctx->transform)(ctx->transformctx,u,&v);CHKERRQ(ierr);}
7226   ierr = VecGetArrayRead(v,&yy);CHKERRQ(ierr);
7227   if (ctx->displaynames) {
7228     PetscInt i;
7229     for (i=0; i<ctx->ndisplayvariables; i++)
7230       ctx->displayvalues[i] = PetscRealPart(yy[ctx->displayvariables[i]]);
7231     ierr = PetscDrawLGAddCommonPoint(ctx->lg,ptime,ctx->displayvalues);CHKERRQ(ierr);
7232   } else {
7233 #if defined(PETSC_USE_COMPLEX)
7234     PetscInt  i,n;
7235     PetscReal *yreal;
7236     ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr);
7237     ierr = PetscMalloc1(n,&yreal);CHKERRQ(ierr);
7238     for (i=0; i<n; i++) yreal[i] = PetscRealPart(yy[i]);
7239     ierr = PetscDrawLGAddCommonPoint(ctx->lg,ptime,yreal);CHKERRQ(ierr);
7240     ierr = PetscFree(yreal);CHKERRQ(ierr);
7241 #else
7242     ierr = PetscDrawLGAddCommonPoint(ctx->lg,ptime,yy);CHKERRQ(ierr);
7243 #endif
7244   }
7245   ierr = VecRestoreArrayRead(v,&yy);CHKERRQ(ierr);
7246   if (ctx->transform) {ierr = VecDestroy(&v);CHKERRQ(ierr);}
7247 
7248   if (((ctx->howoften > 0) && (!(step % ctx->howoften))) || ((ctx->howoften == -1) && ts->reason)) {
7249     ierr = PetscDrawLGDraw(ctx->lg);CHKERRQ(ierr);
7250     ierr = PetscDrawLGSave(ctx->lg);CHKERRQ(ierr);
7251   }
7252   PetscFunctionReturn(0);
7253 }
7254 
7255 /*@C
7256    TSMonitorLGSetVariableNames - Sets the name of each component in the solution vector so that it may be displayed in the plot
7257 
7258    Collective on TS
7259 
7260    Input Parameters:
7261 +  ts - the TS context
7262 -  names - the names of the components, final string must be NULL
7263 
7264    Level: intermediate
7265 
7266    Notes: If the TS object does not have a TSMonitorLGCtx associated with it then this function is ignored
7267 
7268 .keywords: TS,  vector, monitor, view
7269 
7270 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorLGSetDisplayVariables(), TSMonitorLGCtxSetVariableNames()
7271 @*/
7272 PetscErrorCode  TSMonitorLGSetVariableNames(TS ts,const char * const *names)
7273 {
7274   PetscErrorCode    ierr;
7275   PetscInt          i;
7276 
7277   PetscFunctionBegin;
7278   for (i=0; i<ts->numbermonitors; i++) {
7279     if (ts->monitor[i] == TSMonitorLGSolution) {
7280       ierr = TSMonitorLGCtxSetVariableNames((TSMonitorLGCtx)ts->monitorcontext[i],names);CHKERRQ(ierr);
7281       break;
7282     }
7283   }
7284   PetscFunctionReturn(0);
7285 }
7286 
7287 /*@C
7288    TSMonitorLGCtxSetVariableNames - Sets the name of each component in the solution vector so that it may be displayed in the plot
7289 
7290    Collective on TS
7291 
7292    Input Parameters:
7293 +  ts - the TS context
7294 -  names - the names of the components, final string must be NULL
7295 
7296    Level: intermediate
7297 
7298 .keywords: TS,  vector, monitor, view
7299 
7300 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorLGSetDisplayVariables(), TSMonitorLGSetVariableNames()
7301 @*/
7302 PetscErrorCode  TSMonitorLGCtxSetVariableNames(TSMonitorLGCtx ctx,const char * const *names)
7303 {
7304   PetscErrorCode    ierr;
7305 
7306   PetscFunctionBegin;
7307   ierr = PetscStrArrayDestroy(&ctx->names);CHKERRQ(ierr);
7308   ierr = PetscStrArrayallocpy(names,&ctx->names);CHKERRQ(ierr);
7309   PetscFunctionReturn(0);
7310 }
7311 
7312 /*@C
7313    TSMonitorLGGetVariableNames - Gets the name of each component in the solution vector so that it may be displayed in the plot
7314 
7315    Collective on TS
7316 
7317    Input Parameter:
7318 .  ts - the TS context
7319 
7320    Output Parameter:
7321 .  names - the names of the components, final string must be NULL
7322 
7323    Level: intermediate
7324 
7325    Notes: If the TS object does not have a TSMonitorLGCtx associated with it then this function is ignored
7326 
7327 .keywords: TS,  vector, monitor, view
7328 
7329 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorLGSetDisplayVariables()
7330 @*/
7331 PetscErrorCode  TSMonitorLGGetVariableNames(TS ts,const char *const **names)
7332 {
7333   PetscInt       i;
7334 
7335   PetscFunctionBegin;
7336   *names = NULL;
7337   for (i=0; i<ts->numbermonitors; i++) {
7338     if (ts->monitor[i] == TSMonitorLGSolution) {
7339       TSMonitorLGCtx  ctx = (TSMonitorLGCtx) ts->monitorcontext[i];
7340       *names = (const char *const *)ctx->names;
7341       break;
7342     }
7343   }
7344   PetscFunctionReturn(0);
7345 }
7346 
7347 /*@C
7348    TSMonitorLGCtxSetDisplayVariables - Sets the variables that are to be display in the monitor
7349 
7350    Collective on TS
7351 
7352    Input Parameters:
7353 +  ctx - the TSMonitorLG context
7354 .  displaynames - the names of the components, final string must be NULL
7355 
7356    Level: intermediate
7357 
7358 .keywords: TS,  vector, monitor, view
7359 
7360 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorLGSetVariableNames()
7361 @*/
7362 PetscErrorCode  TSMonitorLGCtxSetDisplayVariables(TSMonitorLGCtx ctx,const char * const *displaynames)
7363 {
7364   PetscInt          j = 0,k;
7365   PetscErrorCode    ierr;
7366 
7367   PetscFunctionBegin;
7368   if (!ctx->names) PetscFunctionReturn(0);
7369   ierr = PetscStrArrayDestroy(&ctx->displaynames);CHKERRQ(ierr);
7370   ierr = PetscStrArrayallocpy(displaynames,&ctx->displaynames);CHKERRQ(ierr);
7371   while (displaynames[j]) j++;
7372   ctx->ndisplayvariables = j;
7373   ierr = PetscMalloc1(ctx->ndisplayvariables,&ctx->displayvariables);CHKERRQ(ierr);
7374   ierr = PetscMalloc1(ctx->ndisplayvariables,&ctx->displayvalues);CHKERRQ(ierr);
7375   j = 0;
7376   while (displaynames[j]) {
7377     k = 0;
7378     while (ctx->names[k]) {
7379       PetscBool flg;
7380       ierr = PetscStrcmp(displaynames[j],ctx->names[k],&flg);CHKERRQ(ierr);
7381       if (flg) {
7382         ctx->displayvariables[j] = k;
7383         break;
7384       }
7385       k++;
7386     }
7387     j++;
7388   }
7389   PetscFunctionReturn(0);
7390 }
7391 
7392 /*@C
7393    TSMonitorLGSetDisplayVariables - Sets the variables that are to be display in the monitor
7394 
7395    Collective on TS
7396 
7397    Input Parameters:
7398 +  ts - the TS context
7399 .  displaynames - the names of the components, final string must be NULL
7400 
7401    Notes: If the TS object does not have a TSMonitorLGCtx associated with it then this function is ignored
7402 
7403    Level: intermediate
7404 
7405 .keywords: TS,  vector, monitor, view
7406 
7407 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorLGSetVariableNames()
7408 @*/
7409 PetscErrorCode  TSMonitorLGSetDisplayVariables(TS ts,const char * const *displaynames)
7410 {
7411   PetscInt          i;
7412   PetscErrorCode    ierr;
7413 
7414   PetscFunctionBegin;
7415   for (i=0; i<ts->numbermonitors; i++) {
7416     if (ts->monitor[i] == TSMonitorLGSolution) {
7417       ierr = TSMonitorLGCtxSetDisplayVariables((TSMonitorLGCtx)ts->monitorcontext[i],displaynames);CHKERRQ(ierr);
7418       break;
7419     }
7420   }
7421   PetscFunctionReturn(0);
7422 }
7423 
7424 /*@C
7425    TSMonitorLGSetTransform - Solution vector will be transformed by provided function before being displayed
7426 
7427    Collective on TS
7428 
7429    Input Parameters:
7430 +  ts - the TS context
7431 .  transform - the transform function
7432 .  destroy - function to destroy the optional context
7433 -  ctx - optional context used by transform function
7434 
7435    Notes: If the TS object does not have a TSMonitorLGCtx associated with it then this function is ignored
7436 
7437    Level: intermediate
7438 
7439 .keywords: TS,  vector, monitor, view
7440 
7441 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorLGSetVariableNames(), TSMonitorLGCtxSetTransform()
7442 @*/
7443 PetscErrorCode  TSMonitorLGSetTransform(TS ts,PetscErrorCode (*transform)(void*,Vec,Vec*),PetscErrorCode (*destroy)(void*),void *tctx)
7444 {
7445   PetscInt          i;
7446   PetscErrorCode    ierr;
7447 
7448   PetscFunctionBegin;
7449   for (i=0; i<ts->numbermonitors; i++) {
7450     if (ts->monitor[i] == TSMonitorLGSolution) {
7451       ierr = TSMonitorLGCtxSetTransform((TSMonitorLGCtx)ts->monitorcontext[i],transform,destroy,tctx);CHKERRQ(ierr);
7452     }
7453   }
7454   PetscFunctionReturn(0);
7455 }
7456 
7457 /*@C
7458    TSMonitorLGCtxSetTransform - Solution vector will be transformed by provided function before being displayed
7459 
7460    Collective on TSLGCtx
7461 
7462    Input Parameters:
7463 +  ts - the TS context
7464 .  transform - the transform function
7465 .  destroy - function to destroy the optional context
7466 -  ctx - optional context used by transform function
7467 
7468    Level: intermediate
7469 
7470 .keywords: TS,  vector, monitor, view
7471 
7472 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorLGSetVariableNames(), TSMonitorLGSetTransform()
7473 @*/
7474 PetscErrorCode  TSMonitorLGCtxSetTransform(TSMonitorLGCtx ctx,PetscErrorCode (*transform)(void*,Vec,Vec*),PetscErrorCode (*destroy)(void*),void *tctx)
7475 {
7476   PetscFunctionBegin;
7477   ctx->transform    = transform;
7478   ctx->transformdestroy = destroy;
7479   ctx->transformctx = tctx;
7480   PetscFunctionReturn(0);
7481 }
7482 
7483 /*@C
7484    TSMonitorLGError - Monitors progress of the TS solvers by plotting each component of the error
7485        in a time based line graph
7486 
7487    Collective on TS
7488 
7489    Input Parameters:
7490 +  ts - the TS context
7491 .  step - current time-step
7492 .  ptime - current time
7493 .  u - current solution
7494 -  dctx - TSMonitorLGCtx object created with TSMonitorLGCtxCreate()
7495 
7496    Level: intermediate
7497 
7498    Notes: Each process in a parallel run displays its component errors in a separate window
7499 
7500    The user must provide the solution using TSSetSolutionFunction() to use this monitor.
7501 
7502    Options Database Keys:
7503 .  -ts_monitor_lg_error - create a graphical monitor of error history
7504 
7505 .keywords: TS,  vector, monitor, view
7506 
7507 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSSetSolutionFunction()
7508 @*/
7509 PetscErrorCode  TSMonitorLGError(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dummy)
7510 {
7511   PetscErrorCode    ierr;
7512   TSMonitorLGCtx    ctx = (TSMonitorLGCtx)dummy;
7513   const PetscScalar *yy;
7514   Vec               y;
7515 
7516   PetscFunctionBegin;
7517   if (!step) {
7518     PetscDrawAxis axis;
7519     PetscInt      dim;
7520     ierr = PetscDrawLGGetAxis(ctx->lg,&axis);CHKERRQ(ierr);
7521     ierr = PetscDrawAxisSetLabels(axis,"Error in solution as function of time","Time","Error");CHKERRQ(ierr);
7522     ierr = VecGetLocalSize(u,&dim);CHKERRQ(ierr);
7523     ierr = PetscDrawLGSetDimension(ctx->lg,dim);CHKERRQ(ierr);
7524     ierr = PetscDrawLGReset(ctx->lg);CHKERRQ(ierr);
7525   }
7526   ierr = VecDuplicate(u,&y);CHKERRQ(ierr);
7527   ierr = TSComputeSolutionFunction(ts,ptime,y);CHKERRQ(ierr);
7528   ierr = VecAXPY(y,-1.0,u);CHKERRQ(ierr);
7529   ierr = VecGetArrayRead(y,&yy);CHKERRQ(ierr);
7530 #if defined(PETSC_USE_COMPLEX)
7531   {
7532     PetscReal *yreal;
7533     PetscInt  i,n;
7534     ierr = VecGetLocalSize(y,&n);CHKERRQ(ierr);
7535     ierr = PetscMalloc1(n,&yreal);CHKERRQ(ierr);
7536     for (i=0; i<n; i++) yreal[i] = PetscRealPart(yy[i]);
7537     ierr = PetscDrawLGAddCommonPoint(ctx->lg,ptime,yreal);CHKERRQ(ierr);
7538     ierr = PetscFree(yreal);CHKERRQ(ierr);
7539   }
7540 #else
7541   ierr = PetscDrawLGAddCommonPoint(ctx->lg,ptime,yy);CHKERRQ(ierr);
7542 #endif
7543   ierr = VecRestoreArrayRead(y,&yy);CHKERRQ(ierr);
7544   ierr = VecDestroy(&y);CHKERRQ(ierr);
7545   if (((ctx->howoften > 0) && (!(step % ctx->howoften))) || ((ctx->howoften == -1) && ts->reason)) {
7546     ierr = PetscDrawLGDraw(ctx->lg);CHKERRQ(ierr);
7547     ierr = PetscDrawLGSave(ctx->lg);CHKERRQ(ierr);
7548   }
7549   PetscFunctionReturn(0);
7550 }
7551 
7552 PetscErrorCode TSMonitorLGSNESIterations(TS ts,PetscInt n,PetscReal ptime,Vec v,void *monctx)
7553 {
7554   TSMonitorLGCtx ctx = (TSMonitorLGCtx) monctx;
7555   PetscReal      x   = ptime,y;
7556   PetscErrorCode ierr;
7557   PetscInt       its;
7558 
7559   PetscFunctionBegin;
7560   if (n < 0) PetscFunctionReturn(0); /* -1 indicates interpolated solution */
7561   if (!n) {
7562     PetscDrawAxis axis;
7563     ierr = PetscDrawLGGetAxis(ctx->lg,&axis);CHKERRQ(ierr);
7564     ierr = PetscDrawAxisSetLabels(axis,"Nonlinear iterations as function of time","Time","SNES Iterations");CHKERRQ(ierr);
7565     ierr = PetscDrawLGReset(ctx->lg);CHKERRQ(ierr);
7566     ctx->snes_its = 0;
7567   }
7568   ierr = TSGetSNESIterations(ts,&its);CHKERRQ(ierr);
7569   y    = its - ctx->snes_its;
7570   ierr = PetscDrawLGAddPoint(ctx->lg,&x,&y);CHKERRQ(ierr);
7571   if (((ctx->howoften > 0) && (!(n % ctx->howoften)) && (n > -1)) || ((ctx->howoften == -1) && (n == -1))) {
7572     ierr = PetscDrawLGDraw(ctx->lg);CHKERRQ(ierr);
7573     ierr = PetscDrawLGSave(ctx->lg);CHKERRQ(ierr);
7574   }
7575   ctx->snes_its = its;
7576   PetscFunctionReturn(0);
7577 }
7578 
7579 PetscErrorCode TSMonitorLGKSPIterations(TS ts,PetscInt n,PetscReal ptime,Vec v,void *monctx)
7580 {
7581   TSMonitorLGCtx ctx = (TSMonitorLGCtx) monctx;
7582   PetscReal      x   = ptime,y;
7583   PetscErrorCode ierr;
7584   PetscInt       its;
7585 
7586   PetscFunctionBegin;
7587   if (n < 0) PetscFunctionReturn(0); /* -1 indicates interpolated solution */
7588   if (!n) {
7589     PetscDrawAxis axis;
7590     ierr = PetscDrawLGGetAxis(ctx->lg,&axis);CHKERRQ(ierr);
7591     ierr = PetscDrawAxisSetLabels(axis,"Linear iterations as function of time","Time","KSP Iterations");CHKERRQ(ierr);
7592     ierr = PetscDrawLGReset(ctx->lg);CHKERRQ(ierr);
7593     ctx->ksp_its = 0;
7594   }
7595   ierr = TSGetKSPIterations(ts,&its);CHKERRQ(ierr);
7596   y    = its - ctx->ksp_its;
7597   ierr = PetscDrawLGAddPoint(ctx->lg,&x,&y);CHKERRQ(ierr);
7598   if (((ctx->howoften > 0) && (!(n % ctx->howoften)) && (n > -1)) || ((ctx->howoften == -1) && (n == -1))) {
7599     ierr = PetscDrawLGDraw(ctx->lg);CHKERRQ(ierr);
7600     ierr = PetscDrawLGSave(ctx->lg);CHKERRQ(ierr);
7601   }
7602   ctx->ksp_its = its;
7603   PetscFunctionReturn(0);
7604 }
7605 
7606 /*@
7607    TSComputeLinearStability - computes the linear stability function at a point
7608 
7609    Collective on TS and Vec
7610 
7611    Input Parameters:
7612 +  ts - the TS context
7613 -  xr,xi - real and imaginary part of input arguments
7614 
7615    Output Parameters:
7616 .  yr,yi - real and imaginary part of function value
7617 
7618    Level: developer
7619 
7620 .keywords: TS, compute
7621 
7622 .seealso: TSSetRHSFunction(), TSComputeIFunction()
7623 @*/
7624 PetscErrorCode TSComputeLinearStability(TS ts,PetscReal xr,PetscReal xi,PetscReal *yr,PetscReal *yi)
7625 {
7626   PetscErrorCode ierr;
7627 
7628   PetscFunctionBegin;
7629   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
7630   if (!ts->ops->linearstability) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"Linearized stability function not provided for this method");
7631   ierr = (*ts->ops->linearstability)(ts,xr,xi,yr,yi);CHKERRQ(ierr);
7632   PetscFunctionReturn(0);
7633 }
7634 
7635 /* ------------------------------------------------------------------------*/
7636 /*@C
7637    TSMonitorEnvelopeCtxCreate - Creates a context for use with TSMonitorEnvelope()
7638 
7639    Collective on TS
7640 
7641    Input Parameters:
7642 .  ts  - the ODE solver object
7643 
7644    Output Parameter:
7645 .  ctx - the context
7646 
7647    Level: intermediate
7648 
7649 .keywords: TS, monitor, line graph, residual, seealso
7650 
7651 .seealso: TSMonitorLGTimeStep(), TSMonitorSet(), TSMonitorLGSolution(), TSMonitorLGError()
7652 
7653 @*/
7654 PetscErrorCode  TSMonitorEnvelopeCtxCreate(TS ts,TSMonitorEnvelopeCtx *ctx)
7655 {
7656   PetscErrorCode ierr;
7657 
7658   PetscFunctionBegin;
7659   ierr = PetscNew(ctx);CHKERRQ(ierr);
7660   PetscFunctionReturn(0);
7661 }
7662 
7663 /*@C
7664    TSMonitorEnvelope - Monitors the maximum and minimum value of each component of the solution
7665 
7666    Collective on TS
7667 
7668    Input Parameters:
7669 +  ts - the TS context
7670 .  step - current time-step
7671 .  ptime - current time
7672 .  u  - current solution
7673 -  dctx - the envelope context
7674 
7675    Options Database:
7676 .  -ts_monitor_envelope
7677 
7678    Level: intermediate
7679 
7680    Notes: after a solve you can use TSMonitorEnvelopeGetBounds() to access the envelope
7681 
7682 .keywords: TS,  vector, monitor, view
7683 
7684 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorEnvelopeGetBounds(), TSMonitorEnvelopeCtxCreate()
7685 @*/
7686 PetscErrorCode  TSMonitorEnvelope(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dctx)
7687 {
7688   PetscErrorCode       ierr;
7689   TSMonitorEnvelopeCtx ctx = (TSMonitorEnvelopeCtx)dctx;
7690 
7691   PetscFunctionBegin;
7692   if (!ctx->max) {
7693     ierr = VecDuplicate(u,&ctx->max);CHKERRQ(ierr);
7694     ierr = VecDuplicate(u,&ctx->min);CHKERRQ(ierr);
7695     ierr = VecCopy(u,ctx->max);CHKERRQ(ierr);
7696     ierr = VecCopy(u,ctx->min);CHKERRQ(ierr);
7697   } else {
7698     ierr = VecPointwiseMax(ctx->max,u,ctx->max);CHKERRQ(ierr);
7699     ierr = VecPointwiseMin(ctx->min,u,ctx->min);CHKERRQ(ierr);
7700   }
7701   PetscFunctionReturn(0);
7702 }
7703 
7704 /*@C
7705    TSMonitorEnvelopeGetBounds - Gets the bounds for the components of the solution
7706 
7707    Collective on TS
7708 
7709    Input Parameter:
7710 .  ts - the TS context
7711 
7712    Output Parameter:
7713 +  max - the maximum values
7714 -  min - the minimum values
7715 
7716    Notes: If the TS does not have a TSMonitorEnvelopeCtx associated with it then this function is ignored
7717 
7718    Level: intermediate
7719 
7720 .keywords: TS,  vector, monitor, view
7721 
7722 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorLGSetDisplayVariables()
7723 @*/
7724 PetscErrorCode  TSMonitorEnvelopeGetBounds(TS ts,Vec *max,Vec *min)
7725 {
7726   PetscInt i;
7727 
7728   PetscFunctionBegin;
7729   if (max) *max = NULL;
7730   if (min) *min = NULL;
7731   for (i=0; i<ts->numbermonitors; i++) {
7732     if (ts->monitor[i] == TSMonitorEnvelope) {
7733       TSMonitorEnvelopeCtx  ctx = (TSMonitorEnvelopeCtx) ts->monitorcontext[i];
7734       if (max) *max = ctx->max;
7735       if (min) *min = ctx->min;
7736       break;
7737     }
7738   }
7739   PetscFunctionReturn(0);
7740 }
7741 
7742 /*@C
7743    TSMonitorEnvelopeCtxDestroy - Destroys a context that was created  with TSMonitorEnvelopeCtxCreate().
7744 
7745    Collective on TSMonitorEnvelopeCtx
7746 
7747    Input Parameter:
7748 .  ctx - the monitor context
7749 
7750    Level: intermediate
7751 
7752 .keywords: TS, monitor, line graph, destroy
7753 
7754 .seealso: TSMonitorLGCtxCreate(),  TSMonitorSet(), TSMonitorLGTimeStep()
7755 @*/
7756 PetscErrorCode  TSMonitorEnvelopeCtxDestroy(TSMonitorEnvelopeCtx *ctx)
7757 {
7758   PetscErrorCode ierr;
7759 
7760   PetscFunctionBegin;
7761   ierr = VecDestroy(&(*ctx)->min);CHKERRQ(ierr);
7762   ierr = VecDestroy(&(*ctx)->max);CHKERRQ(ierr);
7763   ierr = PetscFree(*ctx);CHKERRQ(ierr);
7764   PetscFunctionReturn(0);
7765 }
7766 
7767 /*@
7768    TSRestartStep - Flags the solver to restart the next step
7769 
7770    Collective on TS
7771 
7772    Input Parameter:
7773 .  ts - the TS context obtained from TSCreate()
7774 
7775    Level: advanced
7776 
7777    Notes:
7778    Multistep methods like BDF or Runge-Kutta methods with FSAL property require restarting the solver in the event of
7779    discontinuities. These discontinuities may be introduced as a consequence of explicitly modifications to the solution
7780    vector (which PETSc attempts to detect and handle) or problem coefficients (which PETSc is not able to detect). For
7781    the sake of correctness and maximum safety, users are expected to call TSRestart() whenever they introduce
7782    discontinuities in callback routines (e.g. prestep and poststep routines, or implicit/rhs function routines with
7783    discontinuous source terms).
7784 
7785 .keywords: TS, timestep, restart
7786 
7787 .seealso: TSSolve(), TSSetPreStep(), TSSetPostStep()
7788 @*/
7789 PetscErrorCode TSRestartStep(TS ts)
7790 {
7791   PetscFunctionBegin;
7792   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
7793   ts->steprestart = PETSC_TRUE;
7794   PetscFunctionReturn(0);
7795 }
7796 
7797 /*@
7798    TSRollBack - Rolls back one time step
7799 
7800    Collective on TS
7801 
7802    Input Parameter:
7803 .  ts - the TS context obtained from TSCreate()
7804 
7805    Level: advanced
7806 
7807 .keywords: TS, timestep, rollback
7808 
7809 .seealso: TSCreate(), TSSetUp(), TSDestroy(), TSSolve(), TSSetPreStep(), TSSetPreStage(), TSInterpolate()
7810 @*/
7811 PetscErrorCode  TSRollBack(TS ts)
7812 {
7813   PetscErrorCode ierr;
7814 
7815   PetscFunctionBegin;
7816   PetscValidHeaderSpecific(ts, TS_CLASSID,1);
7817   if (ts->steprollback) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_ARG_WRONGSTATE,"TSRollBack already called");
7818   if (!ts->ops->rollback) SETERRQ1(PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"TSRollBack not implemented for type '%s'",((PetscObject)ts)->type_name);
7819   ierr = (*ts->ops->rollback)(ts);CHKERRQ(ierr);
7820   ts->time_step = ts->ptime - ts->ptime_prev;
7821   ts->ptime = ts->ptime_prev;
7822   ts->ptime_prev = ts->ptime_prev_rollback;
7823   ts->steps--;
7824   ts->steprollback = PETSC_TRUE;
7825   PetscFunctionReturn(0);
7826 }
7827 
7828 /*@
7829    TSGetStages - Get the number of stages and stage values
7830 
7831    Input Parameter:
7832 .  ts - the TS context obtained from TSCreate()
7833 
7834    Level: advanced
7835 
7836 .keywords: TS, getstages
7837 
7838 .seealso: TSCreate()
7839 @*/
7840 PetscErrorCode  TSGetStages(TS ts,PetscInt *ns,Vec **Y)
7841 {
7842   PetscErrorCode ierr;
7843 
7844   PetscFunctionBegin;
7845   PetscValidHeaderSpecific(ts, TS_CLASSID,1);
7846   PetscValidPointer(ns,2);
7847 
7848   if (!ts->ops->getstages) *ns=0;
7849   else {
7850     ierr = (*ts->ops->getstages)(ts,ns,Y);CHKERRQ(ierr);
7851   }
7852   PetscFunctionReturn(0);
7853 }
7854 
7855 /*@C
7856   TSComputeIJacobianDefaultColor - Computes the Jacobian using finite differences and coloring to exploit matrix sparsity.
7857 
7858   Collective on SNES
7859 
7860   Input Parameters:
7861 + ts - the TS context
7862 . t - current timestep
7863 . U - state vector
7864 . Udot - time derivative of state vector
7865 . shift - shift to apply, see note below
7866 - ctx - an optional user context
7867 
7868   Output Parameters:
7869 + J - Jacobian matrix (not altered in this routine)
7870 - B - newly computed Jacobian matrix to use with preconditioner (generally the same as J)
7871 
7872   Level: intermediate
7873 
7874   Notes:
7875   If F(t,U,Udot)=0 is the DAE, the required Jacobian is
7876 
7877   dF/dU + shift*dF/dUdot
7878 
7879   Most users should not need to explicitly call this routine, as it
7880   is used internally within the nonlinear solvers.
7881 
7882   This will first try to get the coloring from the DM.  If the DM type has no coloring
7883   routine, then it will try to get the coloring from the matrix.  This requires that the
7884   matrix have nonzero entries precomputed.
7885 
7886 .keywords: TS, finite differences, Jacobian, coloring, sparse
7887 .seealso: TSSetIJacobian(), MatFDColoringCreate(), MatFDColoringSetFunction()
7888 @*/
7889 PetscErrorCode TSComputeIJacobianDefaultColor(TS ts,PetscReal t,Vec U,Vec Udot,PetscReal shift,Mat J,Mat B,void *ctx)
7890 {
7891   SNES           snes;
7892   MatFDColoring  color;
7893   PetscBool      hascolor, matcolor = PETSC_FALSE;
7894   PetscErrorCode ierr;
7895 
7896   PetscFunctionBegin;
7897   ierr = PetscOptionsGetBool(((PetscObject)ts)->options,((PetscObject) ts)->prefix, "-ts_fd_color_use_mat", &matcolor, NULL);CHKERRQ(ierr);
7898   ierr = PetscObjectQuery((PetscObject) B, "TSMatFDColoring", (PetscObject *) &color);CHKERRQ(ierr);
7899   if (!color) {
7900     DM         dm;
7901     ISColoring iscoloring;
7902 
7903     ierr = TSGetDM(ts, &dm);CHKERRQ(ierr);
7904     ierr = DMHasColoring(dm, &hascolor);CHKERRQ(ierr);
7905     if (hascolor && !matcolor) {
7906       ierr = DMCreateColoring(dm, IS_COLORING_GLOBAL, &iscoloring);CHKERRQ(ierr);
7907       ierr = MatFDColoringCreate(B, iscoloring, &color);CHKERRQ(ierr);
7908       ierr = MatFDColoringSetFunction(color, (PetscErrorCode (*)(void)) SNESTSFormFunction, (void *) ts);CHKERRQ(ierr);
7909       ierr = MatFDColoringSetFromOptions(color);CHKERRQ(ierr);
7910       ierr = MatFDColoringSetUp(B, iscoloring, color);CHKERRQ(ierr);
7911       ierr = ISColoringDestroy(&iscoloring);CHKERRQ(ierr);
7912     } else {
7913       MatColoring mc;
7914 
7915       ierr = MatColoringCreate(B, &mc);CHKERRQ(ierr);
7916       ierr = MatColoringSetDistance(mc, 2);CHKERRQ(ierr);
7917       ierr = MatColoringSetType(mc, MATCOLORINGSL);CHKERRQ(ierr);
7918       ierr = MatColoringSetFromOptions(mc);CHKERRQ(ierr);
7919       ierr = MatColoringApply(mc, &iscoloring);CHKERRQ(ierr);
7920       ierr = MatColoringDestroy(&mc);CHKERRQ(ierr);
7921       ierr = MatFDColoringCreate(B, iscoloring, &color);CHKERRQ(ierr);
7922       ierr = MatFDColoringSetFunction(color, (PetscErrorCode (*)(void)) SNESTSFormFunction, (void *) ts);CHKERRQ(ierr);
7923       ierr = MatFDColoringSetFromOptions(color);CHKERRQ(ierr);
7924       ierr = MatFDColoringSetUp(B, iscoloring, color);CHKERRQ(ierr);
7925       ierr = ISColoringDestroy(&iscoloring);CHKERRQ(ierr);
7926     }
7927     ierr = PetscObjectCompose((PetscObject) B, "TSMatFDColoring", (PetscObject) color);CHKERRQ(ierr);
7928     ierr = PetscObjectDereference((PetscObject) color);CHKERRQ(ierr);
7929   }
7930   ierr = TSGetSNES(ts, &snes);CHKERRQ(ierr);
7931   ierr = MatFDColoringApply(B, color, U, snes);CHKERRQ(ierr);
7932   if (J != B) {
7933     ierr = MatAssemblyBegin(J, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
7934     ierr = MatAssemblyEnd(J, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
7935   }
7936   PetscFunctionReturn(0);
7937 }
7938 
7939 /*@
7940     TSSetFunctionDomainError - Set the function testing if the current state vector is valid
7941 
7942     Input Parameters:
7943     ts - the TS context
7944     func - function called within TSFunctionDomainError
7945 
7946     Level: intermediate
7947 
7948 .keywords: TS, state, domain
7949 .seealso: TSAdaptCheckStage(), TSFunctionDomainError()
7950 @*/
7951 
7952 PetscErrorCode TSSetFunctionDomainError(TS ts, PetscErrorCode (*func)(TS,PetscReal,Vec,PetscBool*))
7953 {
7954   PetscFunctionBegin;
7955   PetscValidHeaderSpecific(ts, TS_CLASSID,1);
7956   ts->functiondomainerror = func;
7957   PetscFunctionReturn(0);
7958 }
7959 
7960 /*@
7961     TSFunctionDomainError - Check if the current state is valid
7962 
7963     Input Parameters:
7964     ts - the TS context
7965     stagetime - time of the simulation
7966     Y - state vector to check.
7967 
7968     Output Parameter:
7969     accept - Set to PETSC_FALSE if the current state vector is valid.
7970 
7971     Note:
7972     This function should be used to ensure the state is in a valid part of the space.
7973     For example, one can ensure here all values are positive.
7974 
7975     Level: advanced
7976 @*/
7977 PetscErrorCode TSFunctionDomainError(TS ts,PetscReal stagetime,Vec Y,PetscBool* accept)
7978 {
7979   PetscErrorCode ierr;
7980 
7981   PetscFunctionBegin;
7982 
7983   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
7984   *accept = PETSC_TRUE;
7985   if (ts->functiondomainerror) {
7986     PetscStackCallStandard((*ts->functiondomainerror),(ts,stagetime,Y,accept));
7987   }
7988   PetscFunctionReturn(0);
7989 }
7990 
7991 /*@C
7992   TSClone - This function clones a time step object.
7993 
7994   Collective on MPI_Comm
7995 
7996   Input Parameter:
7997 . tsin    - The input TS
7998 
7999   Output Parameter:
8000 . tsout   - The output TS (cloned)
8001 
8002   Notes:
8003   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.
8004 
8005   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);
8006 
8007   Level: developer
8008 
8009 .keywords: TS, clone
8010 .seealso: TSCreate(), TSSetType(), TSSetUp(), TSDestroy(), TSSetProblemType()
8011 @*/
8012 PetscErrorCode  TSClone(TS tsin, TS *tsout)
8013 {
8014   TS             t;
8015   PetscErrorCode ierr;
8016   SNES           snes_start;
8017   DM             dm;
8018   TSType         type;
8019 
8020   PetscFunctionBegin;
8021   PetscValidPointer(tsin,1);
8022   *tsout = NULL;
8023 
8024   ierr = PetscHeaderCreate(t, TS_CLASSID, "TS", "Time stepping", "TS", PetscObjectComm((PetscObject)tsin), TSDestroy, TSView);CHKERRQ(ierr);
8025 
8026   /* General TS description */
8027   t->numbermonitors    = 0;
8028   t->setupcalled       = 0;
8029   t->ksp_its           = 0;
8030   t->snes_its          = 0;
8031   t->nwork             = 0;
8032   t->rhsjacobian.time  = -1e20;
8033   t->rhsjacobian.scale = 1.;
8034   t->ijacobian.shift   = 1.;
8035 
8036   ierr = TSGetSNES(tsin,&snes_start);CHKERRQ(ierr);
8037   ierr = TSSetSNES(t,snes_start);CHKERRQ(ierr);
8038 
8039   ierr = TSGetDM(tsin,&dm);CHKERRQ(ierr);
8040   ierr = TSSetDM(t,dm);CHKERRQ(ierr);
8041 
8042   t->adapt = tsin->adapt;
8043   ierr = PetscObjectReference((PetscObject)t->adapt);CHKERRQ(ierr);
8044 
8045   t->trajectory = tsin->trajectory;
8046   ierr = PetscObjectReference((PetscObject)t->trajectory);CHKERRQ(ierr);
8047 
8048   t->event = tsin->event;
8049   if (t->event) t->event->refct++;
8050 
8051   t->problem_type      = tsin->problem_type;
8052   t->ptime             = tsin->ptime;
8053   t->ptime_prev        = tsin->ptime_prev;
8054   t->time_step         = tsin->time_step;
8055   t->max_time          = tsin->max_time;
8056   t->steps             = tsin->steps;
8057   t->max_steps         = tsin->max_steps;
8058   t->equation_type     = tsin->equation_type;
8059   t->atol              = tsin->atol;
8060   t->rtol              = tsin->rtol;
8061   t->max_snes_failures = tsin->max_snes_failures;
8062   t->max_reject        = tsin->max_reject;
8063   t->errorifstepfailed = tsin->errorifstepfailed;
8064 
8065   ierr = TSGetType(tsin,&type);CHKERRQ(ierr);
8066   ierr = TSSetType(t,type);CHKERRQ(ierr);
8067 
8068   t->vec_sol           = NULL;
8069 
8070   t->cfltime          = tsin->cfltime;
8071   t->cfltime_local    = tsin->cfltime_local;
8072   t->exact_final_time = tsin->exact_final_time;
8073 
8074   ierr = PetscMemcpy(t->ops,tsin->ops,sizeof(struct _TSOps));CHKERRQ(ierr);
8075 
8076   if (((PetscObject)tsin)->fortran_func_pointers) {
8077     PetscInt i;
8078     ierr = PetscMalloc((10)*sizeof(void(*)(void)),&((PetscObject)t)->fortran_func_pointers);CHKERRQ(ierr);
8079     for (i=0; i<10; i++) {
8080       ((PetscObject)t)->fortran_func_pointers[i] = ((PetscObject)tsin)->fortran_func_pointers[i];
8081     }
8082   }
8083   *tsout = t;
8084   PetscFunctionReturn(0);
8085 }
8086