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