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