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