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